给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
通过次数59,468
提交次数194,425
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
首先考虑题目要求的答案,就是找到最大子串,而且这个字串符合括号匹配原则,那么这样考虑,任何复杂的一串括号,都有最原子括号形式,就是’()’,任何复杂的括号都是这个延申出来的,比如给一个(),我再添加它的兄弟变成了()(),感觉他们暴露在外面不太好,我加个壳变成了(()()),然后又遇到一个新兄弟->(()())(),于是这样演变下去,可以看出来,任何复杂的但是符合条件的括号字符串,都是由单一的()经过两种方式演变来的,要么遇到自己的兄弟,要么被包围起来,于是我们处理的时候就可以先从左往右遍历每个(),然后发现()的左边也有(),就合并起来成()(),那么此时呢?我还可以再判断呀,因为()()是符合条件的,我再判断是否有外壳包围起来,或者左边还没有这样的兄弟,如果没有了继续往下,突然就遇到一个新的()马上再往左边看,看到了()(),太棒了,马上连接起来成了()()(),但是你怎么快速可以看到左边的()()呢?这个需要我们标记一下啦,我们不管结构,但凡是符合条件的子串,也就是不管是(())还是()()这样的结构,我们用sign定位到最右边的位置,然后vis[sign]就表示最左边的位置,这样判断就很方便啦。
AC代码
class Solution {
public:
int longestValidParentheses(string s)
{
int vis[1000000];
memset(vis,-1,sizeof(vis));
for(int i=0;i<s.length();i++)
{
if(s[i]=='('&&i+1<s.length()&&s[i+1]==')')
{
//标记定位到最左边
vis[i+1]=i;
//sign永远指向最右边
int sign=i+1;
while(true)
{
bool flag=true;
//表示左边的可以合并
//比如()(())->此时sign=5,vis[sign]=2,才能判断
if(vis[sign]-1>=0&&vis[vis[sign]-1]>=0)
{
flag=false;
vis[sign]=vis[vis[sign]-1];
}
//包起来战略
if(sign+1<s.length()&&s[sign+1]==')'&&(vis[sign]-1>=0)&&s[vis[sign]-1]=='(')
{
flag=false;
vis[sign+1]=vis[sign]-1;
//移到最右边
sign=sign+1;
}
//已经不可再更新了
if(flag)
break;
}
}
}
int ans=0;
for(int i=0;i<s.length();i++)
{
if(vis[i]==-1)continue;
ans=max(ans,i-vis[i]+1);
}
return ans;
}
};
希望我的分享对你的学习有所帮助,如有问题请及时指出,谢谢~