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.

 

方法一:设dp[i][j]表示以i开始长度为j的字符串是否为符合要求的括号形式,其中j = 2, 4, 6 ....那么有

当dp[i+1][j-2] = true and s[i] = '(' and s[i+j-1] = ')' 或 dp[i][k] = true and dp[i+k][j-k] = true,(k = 2, 4...j-2)

则有dp[i][j] = true; 否则为false,计算的过程中可以直接求出最长的括号子串长度。不过时间复杂度为O(n2),结果超时,代码如下:

 

 1 class Solution {
 2 public:
 3     int longestValidParentheses(string s) {
 4         const int len = s.length();
 5         bool dp[len][len+1];    //dp[i][j]表示以i开始长度为j的字符串
 6         memset(dp, 0, sizeof(dp));
 7         int ans = 0;    //最长符合要求的括号长度
 8         for(int i=0; i+2 <= len; ++i)   //初始化长度为2的字符串
 9             if( s[i] == '(' && s[i+1] == ')' )
10                 dp[i][2] = true, ans = 2;
11         for(int j=4; j<len; j+=2)   //字符长度逐步递增,步长为2
12             for(int i=0; i+j<=len; ++i) {   //状态转移,见分析
13                 if( dp[i+1][j-2] && s[i] == '(' && s[i+j-1] == ')' )
14                     dp[i][j] = true;
15                 else {
16                     for(int k = 2; k+2<=j; k+=2)
17                         if( dp[i][k] && dp[i+k][j-k] ) {
18                             dp[i][j] = true;
19                             break;
20                         }
21                 }
22                 if( dp[i][j] ) ans = j;
23             }
24         return ans;
25     }
26 };

 

方法二:leetcode讨论组大牛的方法,使用一个stack,只存左括号的下标,last变量存放最后一个无法匹配的')',遍历字符串,如果遇到'(',下标就放入栈中,如果入到')',则分两种情况,一种是栈为空,那么说明')'无法被匹配,更新last,另一种栈不为空,那么pop出一个'(',此时如果栈为空,说明可以得到完整的符合要求的长度,长度为i-last,如果栈不为空,说明栈还有'('没有被匹配,那么目前合法的长度为i-st.top(),时间复杂度为O(n),代码如下:

 1 class Solution {
 2 public:
 3     int longestValidParentheses(string s) {
 4         int ans = 0, last = -1; //ans表示最大合法长度,last最后一个无法匹配的')'的下标
 5         stack<int> st;
 6         for(int i=0; i<s.length(); ++i)
 7             if( s[i] == '(' ) st.push(i);   //遇到左括号,就放入左括号的下标
 8             else {  //遇到右括号
 9                 if( st.empty() )    //如果栈空,更新last
10                     last = i;
11                 else {  //栈非空
12                     st.pop();   //pop出一个'('
13                     if( st.empty() ) ans = max(ans, i-last);    //此时如果栈空,那么就是个完整的合法长度,即i-last
14                     else ans = max(ans, i-st.top());    //如果栈非空,那么局部合法长度即为i-st.top()
15                 }
16             }
17         return ans;
18     }
19 };

 

posted on 2014-09-03 10:40  bug睡的略爽  阅读(223)  评论(3编辑  收藏  举报

导航