leetcode32-最長有效括號
給定一個只包含 ‘(’ 和 ‘)’ 的字符串,找出最長的包含有效括號的子串的長度。
示例1:
輸入: "(()"
輸出: 2
解釋: 最長有效括號子串爲 "()"
示例2:
輸入: ")()())"
輸出: 4
解釋: 最長有效括號子串爲 "()()"
題解
動態規劃(官方題解)
這個問題可以通過動態規劃解決。我們定義一個 dp 數組,其中第 i 個元素表示以下標爲 i 的字符結尾的最長有效子字符串的長度。我們將 dp 數組全部初始化爲 0 。現在,很明顯有效的子字符串一定以 ‘)’ 結尾。這進一步可以得出結論:以 ‘(’ 結尾的子字符串對應的 dp 數組位置上的值必定爲 0 。所以說我們只需要更新 ‘)’ 在 dp 數組中對應位置的值。
爲了求出 dp 數組,我們每兩個字符檢查一次,如果滿足如下條件:
-
s[i]=‘)’ 且 s[i−1]=‘(’ ,也就是字符串形如"…()",我們可以推出:
我們可以進行這樣的轉移,是因爲結束部分的 “()” 是一個有效子字符串,並且將之前有效子字符串的長度增加了 2 。 -
s[i]=‘)’ 且 s[i−1]=‘)’,也就是字符串形如 “…))”,我們可以推出
如果 s[i−dp[i−1]−1]=‘(’ ,那麼
這背後的原因是如果倒數第二個‘)’ 是一個有效子字符串的一部分(記爲),對於最後一個‘)’ ,如果它是一個更長子字符串的一部分,那麼它一定有一個對應的‘(’ ,它的位置在倒數第二個‘)’ 所在的有效子字符串的前面(也就是的前面)。因此,如果子字符串的前面恰好是 ‘(’ ,那麼我們就用 2 加上的長度(dp[i−1])去更新dp[i]。除此以外,我們也會把有效子字符串 “”
,)"之前的有效子字符串的長度也加上,也就是加上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;
}
};