leetcode32-最長有效括號

leetcode32-最長有效括號

給定一個只包含 ‘(’ 和 ‘)’ 的字符串,找出最長的包含有效括號的子串的長度。

示例1:

輸入: "(()"
輸出: 2
解釋: 最長有效括號子串爲 "()"

示例2:

輸入: ")()())"
輸出: 4
解釋: 最長有效括號子串爲 "()()"

題解

動態規劃(官方題解)

這個問題可以通過動態規劃解決。我們定義一個 dp 數組,其中第 i 個元素表示以下標爲 i 的字符結尾的最長有效子字符串的長度。我們將 dp 數組全部初始化爲 0 。現在,很明顯有效的子字符串一定以 ‘)’ 結尾。這進一步可以得出結論:以 ‘(’ 結尾的子字符串對應的 dp 數組位置上的值必定爲 0 。所以說我們只需要更新 ‘)’ 在 dp 數組中對應位置的值。

爲了求出 dp 數組,我們每兩個字符檢查一次,如果滿足如下條件:

  1. s[i]=‘)’ 且 s[i−1]=‘(’ ,也就是字符串形如"…()",我們可以推出:
    dp[i]=dp[i2]+2dp[i]=dp[i−2]+2
    我們可以進行這樣的轉移,是因爲結束部分的 “()” 是一個有效子字符串,並且將之前有效子字符串的長度增加了 2 。

  2. s[i]=‘)’ 且 s[i−1]=‘)’,也就是字符串形如 “…))”,我們可以推出
    如果 s[i−dp[i−1]−1]=‘(’ ,那麼
    dp[i]=dp[i1]+dp[idp[i1]2]+2dp[i]=dp[i−1]+dp[i−dp[i−1]−2]+2

這背後的原因是如果倒數第二個‘)’ 是一個有效子字符串的一部分(記爲subssub_s),對於最後一個‘)’ ,如果它是一個更長子字符串的一部分,那麼它一定有一個對應的‘(’ ,它的位置在倒數第二個‘)’ 所在的有效子字符串的前面(也就是subssub_s的前面)。因此,如果子字符串subssub_s的前面恰好是 ‘(’ ,那麼我們就用 2 加上subssub_s的長度(dp[i−1])去更新dp[i]。除此以外,我們也會把有效子字符串 “(,subs,)(,sub_s,)

,)"之前的有效子字符串的長度也加上,也就是加上dp[i−dp[i−1]−2]。

作者:LeetCode
鏈接:https://leetcode-cn.com/problems/longest-valid-parentheses/solution/zui-chang-you-xiao-gua-hao-by-leetcode/
來源:力扣(LeetCode)

class Solution {
public:
    int longestValidParentheses(string s) {
        // #dp法
        int count=0;
        int Slen=s.size();
        if(Slen==0) return 0;
        int dp[Slen]={0};
        for(int i=1;i<Slen;i++){
            if(s[i]==')'){
                if(s[i-1]=='('){
                    dp[i]=(i>=2?dp[i-2]:0)+2;
                }else if(i-dp[i-1]>0 && s[i-dp[i-1]-1]=='('){
                    dp[i]=dp[i-1]+((i-dp[i-1])>=2?dp[i-dp[i-1]-2]:0)+2;
                }
            }
            count = max(count,dp[i]);
        }
        return count;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章