Leetcode: Longest Valid Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

分析:这里我们分析解决这道题的两种方法,一种是利用栈,另一种是动态规划。

1. 利用栈,时间复杂度O(n), 空间复杂度O(n)

在valid parentheses中,我们用最后栈是否为空,判断是否为valid parentheses。这里要求longest valid parentheses,我们要在valid parentheses的基础上做些改动。我们首先应该考虑的是,对于每一段valid parentheses,我们怎么记录它的长度,如果在遍历过程中求的每一段valid parentheses的长度,我们可以轻松的找出最长的。 通过观察可以发现,当前valid parentheses的长度为当前')'的index减去栈顶'('的index(此时与当前')'匹配的'('已被pop出)。如果当栈为空时,我们无法通过上述方法求的长度,此种情况,或者该valid parentheses段前面有')'或者前面没有任何字符,这两种情况我们可以通过记录上一次栈空时')'的index,然后当前')'的index减去上一次')'的index即为valid parentheses段的长度。代码如下:

 1 class Solution {
 2 public:
 3     int longestValidParentheses(string s) {
 4         int n = s.length();
 5         if(n == 0) return 0;
 6         int longest = 0, last = -1;//last is the index of last ')'
 7         stack<int> S;
 8         
 9         for(int i = 0; i < n; i++){
10             if(s[i] == '(') S.push(i);
11             else if(S.empty()){
12                 last = i;
13             }else{
14                 S.pop();
15                 if(S.empty()) longest = max(longest, i - last);
16                 else longest = max(longest, i - S.top());
17             }
18         }
19         return longest;
20     }
21 };

2. 动态规划,时间复杂度O(n), 空间复杂度O(n)。

我们用f[i]记录在[i, n-1]段中从i开始的valid parentheses最大长度。递推公式如下:

if(i+f[i+1]+1 < n && s[i] == '(' && s[i+f[i+1]+1] == ')') f[i] = f[i+1] + 2 +(i+f[i+1] +2 < n)?f[i+f[i+1]+2]:0;otherwise f[i] = 0.

代码如下:

 1 class Solution {
 2 public:
 3 int longestValidParentheses(string s) {
 4 vector<int> f(s.size(), 0);
 5 int ret = 0;
 6 for (int i = s.size() - 2; i >= 0; --i) {
 7 int match = i + f[i + 1] + 1;
 8 // case: "((...))"
 9 if (s[i] == '(' && match < s.size() && s[match] == ')') {
10 f[i] = f[i + 1] + 2;
11 // if a valid sequence exist afterwards "((...))()"
12 if (match + 1 < s.size()) f[i] += f[match + 1];
13 }
14 ret = max(ret, f[i]);
15 }
16 return ret;
17 }
18 };

 

posted on 2014-12-04 19:15  Ryan-Xing  阅读(167)  评论(0编辑  收藏  举报