题意
给一个只包含 '(' 和 ')' 的字符串,求最长有效括号子序列的长度。
如 "(()" 的最长有效括号子序列的长度为2。
思路
动态规划。 dp[i] 表示从下标 i 开始向左数,有效括号子序列的长度。
1° 若 s[i] == '(' ,则 dp[i] = 0
2° 若 s[i] == ')' ,上一个可能与 s[i] 匹配的位置 j = i-1-dp[i-1]
2.1° 若 s[j] == ')' ,不能匹配,dp[i] = 0
2.2° 若 s[j] == '(' ,表示可以匹配,dp[i] = dp[i-1] + 2。若 s[j-1] == ')',表示起始处为 i 的这一段与起始处为 j-1 的这一段可以合并起来(如果根本没有从 j-1 开始的那一段, dp[j-1] == 0,也是没问题的),dp[i] += dp[j-1]
最后找出数组 dp 中的最大元素即可。
C++代码
class Solution { public: int longestValidParentheses(string s) { if(s.size()<2) return 0; int n=s.size(); vector<int> dp(n+10,0); int ans=0; for(int i=1;i<n;i++) { if(s[i]=='(') continue; int last=i-1-dp[i-1]; if(last>=0 && s[last]=='(') { dp[i]=dp[i-1]+2; if(last>=1 && s[last-1]==')') dp[i]+=dp[last-1]; } ans=max(ans,dp[i]); } return ans; } };
python代码
class Solution: def longestValidParentheses(self, s): """ :type s: str :rtype: int """ n = len(s) if n < 2: return 0 ans = 0 dp = [0] * (n+10) for i in range(0, n): if s[i] == '(': continue last = i - 1 - dp[i-1] if last >= 0 and s[last] == '(': dp[i] = dp[i-1] + 2 if last >= 1 and s[last-1] == ')': dp[i] += dp[last-1] ans = max(ans, dp[i]) return ans