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)

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