题目链接:力扣https://leetcode-cn.com/problems/longest-valid-parentheses/
题意:
给你一个只包含
'('
和')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
方法一: 两重循环O(n^2),滑动窗口,寻找最长括号子串
class Solution {
public:
int longestValidParentheses(string s) {
int size = s.size();//定义字符串长度
int index = 0;//标注滑动窗口左侧坐标
int ans = 0;//最后要返回的结果
while(index<size)//不断地滑动窗口
{
int left = 0,right = 0;//左括号数目,右括号数目
int len = 0;//长度
int i;//暂存i
for(i=index;i<size;i++)
{
if(s[i]=='(') left++;//统计左括号数目
else right++;//统计右括号数目
len++;//字符串长度自加
if(left<right)//当右括号数目大于左括号数目
{
index = i+1;//i前面的这一段全部放弃,滑动窗口滑动
ans = max(ans,len-1);//顺带更新一下最大长度
break;//跳出循环
}else if(left==right)//如果左右括号刚好相等
ans = max(ans,len); //更新一下最大长度
}
if(i==size) index++;//正常结束就说明没有被放弃,滑动窗口往右滑动1个单位
}
return ans;//返回结果
}
};
方法二:动态规划
class Solution {
public:
int longestValidParentheses(string s) {
int size = s.size();//定义字符串长度
vector<int> dp(size,0);//dp[i]表示以i为结尾的最大长度
int ans = 0;//返回结果
for(int i=1;i<size;i++)//首个元素是左括号或者右括号都是dp都是0
{
if(s[i]==')') //当前字符是右括号
{
if(s[i-1]=='(')//前一个字符是左括号
{
dp[i] = 2;//当前最大长度是2
if(i-2>=0)//假如序号比2大
dp[i] += dp[i-2];//加上前前个字符之前的最大长度
}else//前一个字符是右括号
{
if(i-dp[i-1]-1>=0&&s[i-dp[i-1]-1]=='(')//找对称,首先要判断找到对称的字符是否存在,如果存在要判断它是不是左括号
{
dp[i] = dp[i-1] + 2;//如果是的话,最长长度就是前一个的最长长度的基础上加2
if(i-dp[i-1]-2>=0)//假如对称的字符的前一个字符存在,那么还得加上它的长度
dp[i]+=dp[i-dp[i-1]-2];
}
}
ans = max(dp[i],ans);//更新最大长度
}
}
return ans;//返回结果
}
};