Longest Valid Parentheses

一. 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.

Difficulty:Hard

TIME:TIMEOUT

解法一(动态规划)

看到这道题的时候,就想起了求最长回文子序列的问题,不过两道题的解法并不相同。

如果用一个数组表示以括号字符”)”结尾的最长有效括号序列,这道题最优子结构可以描述为,并且用字母s表示输入字符串:

  • 如果s[i]==’)’ && s[i - 1]==’(‘,那么dp[i]=dp[i-2]+2;
  • 如果s[i]==’)’ && s[i - dp[i-1]-1] ==’(‘,那么dp[i]=dp[i-1]+2+dp[i-dp[i-1]-2];

更直观的表达就是这样:

  • 第一种情况可以称之为扩展,比如形如()()。
  • 第二种情况可以称之为包含,比如形如(())。

对于有效括号序列来说,要不就是扩展,要不就是包含,没有第三种情况。

int longestValidParentheses(string s) {
    if(s.size() < 2)
        return 0;
    vector<int> dp(s.size(),0);  //记录以')'结尾的最长有效括号长度
    int len = 0;
    for(int i = 1; i < s.size(); i++) {
        if(s[i] == ')' && s[i - 1] == '(')  //扩展
            dp[i] = i - 2 >= 0 ? dp[i - 2] + 2 : 2;
        else if(s[i] == ')' && s[i - dp[i - 1] - 1] == '(') //包含
            //注意这里包含之后还要再扩展一次
            dp[i] = i - dp[i - 1] - 2 >= 0 ? dp[i - 1] + 2 + dp[i - dp[i - 1] - 2] : dp[i - 1] + 2;
        len = max(len, dp[i]);
    }
    return len;
}

代码的时间复杂度为O(n)

解法二(贪心算法)

这道题也可以用贪心来求解,不过需要用到栈。分为以下几种情况。

  • 当遇到’(‘,将该字符的下标压入栈中
  • 当遇到’)’,如果这个时候栈为空,说明字符’)’是多余的,因此字符序列可以从这里断开
  • 当遇到’)’,这个时候栈不为空,这个时候就从栈中弹出一个下标,弹出下标之后如果栈为空,说明这个字符序列完全是有效括号序列,如果弹出下标后栈不为空,说明这个字符序列只有部分是有效括号序列,起始位置为栈顶的下标。
int longestValidParentheses(string s) {
    if(s.size() < 2)
        return 0;
    vector<int> v;
    int left = -1;
    int len = 0;
    for(int i = 0; i < s.size(); i++) {
        if(s[i] == '(')
            v.push_back(i);
        else if(v.empty())
            left = i;
        else {
            v.pop_back();
            if(v.empty())
                len = max(len, i - left); //栈中元素完全匹配
            else
                len = max(len, i - v.back()); //栈中元素不完全匹配,计算部分长度
        }
    }
    return len;
}

代码的时间复杂度为O(n)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章