这种题感觉难度极大,关键在于找到状态函数以及状态转移方程。
leetcode32. Longest Valid Parentheses挺有代表性
dp[i]代表s[:i],以s[i]为末尾的最长字串。
当遇到----()的时候,+2,则为遇到有效的一对括号,则+2
当遇到----))的时候,无法通过末尾判定是不是有效的。
s[i-1]处,有d[i-1]长度的有效字符串,那么,只能越过这么长的字符串,寻找有没有(。
也就是判断s[i-1-d[i-1]]==‘('。如果是,证明s[i]这个字符是有效的字符。
那如何更新dp呢?
在这里,不可以直接取dp[i-1]+2,因为s[i-1-d[i-1]]此时也是有效字符了,那么,需要加上dp[i-1-dp[i-1]-1],也就是之前的有效字符长度。
比如
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
s | ( | ) | ( | ( | ) | ( | ) | ) |
dp | 0 | 2 | 0 | 0 | 2 | 0 | 4 | 8 |
判断到7的时候,需要找2是不是'(',找到后,需要把0-1的()也连接上,所以就是4+2+2=8
class Solution {
public:
int longestValidParentheses(string s) {
int l = s.size();
if(l==0)
return 0;
vector<int> dp(l, 0);
int maxval = 0;
for(int i=1; i<l; i++){
if(s[i] == ')'){
if(s[i-1] == '('){
if(i-2>=0)
dp[i] = dp[i - 2] + 2;
else
dp[i] = 2;
maxval = (dp[i] > maxval)?dp[i]:maxval;
} else {
if(i - 1 - dp[i-1] >=0 && s[i-1-dp[i-1]]=='('){
if(i-2-dp[i-1] >=0)
dp[i] = dp[i-1-dp[i-1]-1] + dp[i-1] + 2;
else
dp[i] = dp[i-1] + 2;
maxval = (dp[i] > maxval)?dp[i]:maxval;
}
}
}
}
return maxval;
}
};