问题
https://leetcode.com/problems/longest-valid-parentheses/
解法一
首先找到所有不能匹配的‘)’ 和 ‘(’ 将s分为若干部分,每一部分子串都是合法的。只需要统计最长子串即可。找到不匹配的’)’ 只需要从前往后遍历一遍s即可。所以复杂度为2N;
class Solution {
public:
int longestValidParentheses(string s) {
int ret = 0;
int now = 0;
int Lnum =0;
int Rnum = 0;
if (s.size() < 2)
return 0;
bool valid[s.size()];
memset(valid, 1, sizeof(valid));
for (int i=s.size()-1; i>=0; --i)
{
if (s[i] == ')')
Rnum++;
else
if (Rnum)
Rnum--;
else
valid[i] = false;
}
for (int i=0; i< s.size(); ++i)
{
if (s[i]=='(')
{
if (valid[i])
Lnum++;
else
{
ret = max(ret, now);
now = 0;
Lnum = 0;
}
}else{
if (Lnum)
{
Lnum--;
now+=2;
}else{
ret = max(ret, now);
now = 0;
Lnum = 0;
}
}
}
ret = max(ret, now);
return ret;
}
};
解法二
使用dp求解,每个状态f(i) 表示以i结尾的最长合格串的长度。
递推关系为如果A[i] = ‘(’ 则 f(i) = 0;
如果A[i] = ‘)’ 则判断f(i-1) 表示的串之前一个字符是否为 ‘(’
如果是则匹配, 长度为f(i-1) +2 + f(i-f(i-1)-1-1)。
例如:
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
A[i] | ( | ( | ) | ) | ( | ( | ) | ) | ( | ) | ) |
f[i] | 0 | 0 | 2 | 4 | 0 | 0 | 2 | ? |
f(7) 处 A[7] =’)’ && A[4] =’(’ 产生匹配,所以A[4~7] 是合法的。
由于A[0~3]也是合法的,所以A[0~7] 都是合法。
如果不匹配则A[i] = 0;
class Solution {
public:
int longestValidParentheses(string s) {
if (s.size() < 2) return 0;
int dp[s.size()];
dp[0] = 0;
int ret = 0;
for (int i=1; i<s.size(); i++)
{
if (s[i] == '(')
{
dp[i] = 0;
}else{
int j = i-dp[i-1]-1;
if (j >=0 && s[j] == '(')
{
dp[i] = dp[i-1]+2;
if (j-1>=0)
dp[i] += dp[j-1];
}else{
dp[i] = 0;
}
ret = max(ret, dp[i]);
}
}
return ret;
}
};