Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
For “(()”, the longest valid parentheses substring is “()”, which has length = 2.
Another example is “)()())”, where the longest valid parentheses substring is “()()”, which has length = 4.
解法一:用两个指针对下标进行枚举,用一个函数判断这个子串是否有效,并比较长度和最大值。用栈实现。217/229 Passed,超时。
class Solution {
public:
bool judge(string str)
{
stack<char> s;
int len = str.length();
for(int i=0;i<len;i++)
{
if(str[i] == '(')
s.push(str[i]);
else
{
if(s.empty())
return false;
if(s.top() == '(')
s.pop();
else
return false;
}
}
if(s.empty())
return true;
return false;
}
int longestValidParentheses(string s)
{
int len = s.length();
int mmax = 0;
for(int i=0;i<len;i++)
{
for(int j=i+1;j<len;j+=2) //长度肯定是偶数
{
string tmp = s.substr(i,j-i+1);
//cout<<tmp<<endl;
if(judge(tmp))
{
if(j-i+1 > mmax)
mmax = j-i+1;
}
}
}
return mmax;
}
};
解法二:二维动态规划。对子串长度进行动规,按理说时间复杂度够,但是交上去之后内存爆炸。
class Solution {
public:
int dp[1000][1000];//dp[i][j]=1 表示 i 到 j 是有效的
int longestValidParentheses(string s)
{
int len = s.length();
int mmax = 0;
int dp_len = 0; //当前动归的子串长度
if(len==0 || len==1)
{
return 0;
}
//初始化
for(int i=0;i<len;i++)
dp[i][i] = 0;
for(int i=0;i<len-1;i++)
{
if(s[i]=='(' && s[i+1]==')')
{
dp[i][i+1] = 1;
mmax = 2;
}
}
for(dp_len=4;dp_len<=len;dp_len+=2)
{
for(int i=0;i+dp_len-1<len;i++)
{
int flag = 0;
int j = i+dp_len-1; //动归dp[i][j];
if(dp[i+1][j-1] == 1)
{
if(s[i]=='(' && s[j]==')')
{
dp[i][j] = 1; flag = 1; //当前子串已经为1,不用再找下面的
}
}
if(flag == 0)
{
if(dp[i][j-2] == 1)
{
if(s[j-1]=='(' && s[j]==')')
{
dp[i][j] = 1; flag = 1;
}
}
}
if(flag == 0)
dp[i][j] = 0;
else
{
if(dp_len > mmax)
mmax = dp_len;
}
}
}
return mmax;
}
};
解法三:一维动态规划,时间复杂度O(n)
dp[i] 表示以 i 为结尾的子串的有效括号匹配长度
若s[i]和s[i-1]能够匹配,那么dp[i] = dp[i-2]+2;
若不能匹配,考虑dp[i-1],即以s[i-1]为结尾的最大匹配长度,然后看s[i]与s[i-dp[i-1]-1]是否能匹配。若能匹配,再加上最前面的一段。
class Solution {
public:
int dp[100000];//dp[i] 表示以 i 为结尾的子串的有效括号匹配长度
int longestValidParentheses(string s)
{
int len = s.length();
int mmax = 0;
if(len==0 || len==1)
return 0;
//初始化
dp[0] = 0;
for(int i=1;i<len;i++)
{
if(s[i]==')' && s[i-1]=='(')
{
dp[i] = 2; mmax = 2;
}
else
dp[i] = 0;
}
if(len >= 4)
{
for(int i=3;i<len;i++)
{
dp[i] = 0;
if(s[i] == '(')
continue;
else
{
if(s[i-1] == '(')
dp[i] = dp[i-2]+2;
else if(dp[i-1] < i) //前面还可以匹配
{
if(s[i-dp[i-1]-1] == '(')
{
dp[i] = dp[i-1]+2;
if(i-dp[i-1]-2 >= 0)
dp[i] += dp[i-dp[i-1]-2];
}
}
}
}
}
for(int i=0;i<len;i++)
{
if(dp[i] > mmax)
mmax = dp[i];
}
return mmax;
}
};