给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = “(()”
输出:2
解释:最长有效括号子串是 “()”
示例 2:
输入:s = “)()())”
输出:4
解释:最长有效括号子串是 “()()”
示例 3:
输入:s = “”
输出:0
提示:
0 <= s.length <= 3 * 104
s[i] 为 ‘(’ 或 ‘)’
以下有三种思路,有的能通过,有的超时,仅提供大概思路;
①暴力:
class Solution {
public:
int longestValidParentheses(string s)
{
stack<char> myStack;
int len = s.size();
if(len % 2 == 1) len--;
int result = 0;
while(len)
{
for(int i_out = len - 1; i_out < s.size(); ++i_out)
{
for(int i = i_out - len + 1; i <= i_out ; ++i)
{
//最后一个如果是左括号直接跳出这层for循环
//否则直接入栈
if(s[i] == '(')
{
if(i == i_out)
break;
myStack.push(s[i]);
}
if(s[i] == ')')
{
if(myStack.empty())
break;
myStack.pop();
result += 2;
}
}//内层for
if(result == len)
return len;
else
{
result = 0;
while(!myStack.empty())
myStack.pop();
}
}//外层for
if(result == len)
return len;
else
{
result = 0;
while(!myStack.empty())
myStack.pop();
len -= 2;
}
}//while
return 0;
}
};
②:动态规划:
class Solution {
public:
int longestValidParentheses(string s)
{
//dp[i]表示包含s[i]在内的最长有效括号子串长度
//即如果s[i]是左括号,则赋值dp[i]=0,因为包含s[i]在内的子串无法有效匹配
//转移方程为dp[i] = dp[i-1] + 2 + dp[i - dp[i-1] - 2];
int len = s.size();
int max = 0;
vector<int> dp(len+1,0);
dp[0] = 0;
for(int i = 1; i < s.size(); ++i)
{
if(s[i] == ')')
{
if(s[i-1] == '(')
dp[i] = (i>=2?dp[i-2]:0) + 2;
else
{
if(i-dp[i-1]-1>=0 && s[i-dp[i-1]-1] == '(')
dp[i] = 2 + dp[i-1] + ((i-dp[i-1])>= 2? dp[i-dp[i-1]-2] : 0);
}
}
if(dp[i] > max)
max = dp[i];
}
return max;
}
};
③栈: