第一种方法,用栈实现,最容易想到,也比较容易实现,每次碰到‘)’时update max_len,由于要保存之前的‘(’的index,所以space complexity 是O(n)
1 // 使用栈,时间复杂度 O(n),空间复杂度 O(n) 2 class Solution { 3 public: 4 int longestValidParentheses(string s) { 5 int max_len = 0, last = -1; 6 stack<int> lefts; 7 for (int i = 0; i < s.size(); ++i) { 8 if (s[i] =='(') { 9 lefts.push(i); 10 } else { 11 if (lefts.empty()) { 12 // update last 13 last = i; 14 } else { 15 // find a matching pair 16 lefts.pop(); 17 if (lefts.empty()) { 18 max_len = max(max_len, i-last); 19 } else { 20 max_len = max(max_len, i-lefts.top());21 } 22 } 23 } 24 } 25 return max_len; 26 } 27 };
第二种方方法,搞一个计数器,每次遇到'('加一,遇到‘)’ 减少一,所以只有在计数器==0的时候更新 max_len。为了实现功能,必须两侧扫描,从而在计数器==0的时候更新max_len.
例如( ( () () 由于左括号多,因此从左侧扫描无法达到计数器==0,所以,max_len还是0.但当从右侧扫描是,右括号较少,会达到0,从而得到真实的max_len.保存start的思想和栈方法一致。
1 // LeetCode, Longest Valid Parenthese 2 // 两遍扫描,时间复杂度 O(n),空间复杂度 O(1) 3 // @author 曹鹏 4 class Solution { 5 public: 6 int longestValidParentheses(string s) 7 { 8 int answer = 0, depth = 0, start = -1; 9 for (int i = 0; i < s.size(); ++i) { 10 if (s[i] == '(') { 11 ++depth; 12 } else { 13 --depth; 14 if (depth < 0) { 15 start = i; 16 depth = 0; 17 } else if (depth == 0) { 18 answer = max(answer, i - start); 19 } 20 } 21 } 22 depth = 0; 23 start = s.size(); 24 for (int i = s.size() - 1; i >= 0; --i) { 25 if (s[i] == ')') { 26 ++depth; 27 } else { 28 --depth; 29 if (depth < 0) { 30 start = i; 31 depth = 0; 32 } else if (depth == 0) { 33 answer = max(answer, start - i); 34 } 35 } 36 } 37 return answer; 38 } 39 };