解题思路:
看到括号匹配的题,第一反应是用一个stack来模拟,可是这题要寻找最长的有效括号匹配,那是否依然可以利用stack来模拟呢?答案是可以的.
假设我们的stack只存左括号的index,并且只从第一个左括号开始模拟(毕竟前面全是右括号肯定不在有效括号匹配内),那么我们会遇到以下几种情况:
1)遇到右括号,stack为空
2)遇到右括号,stack不为空
3)遇到左括号,stack为空
4)遇到左括号,stack不为空.
下面我们针对每种情况一一处理.
1)这表示该括号之前的所有的括号都匹配了,这时我们需要计算这段匹配的长度是否比全局长度大,全局长度取较大值,
同时表示下一段有效长度和这段一定不相连,清空栈,寻找到下一个左括号,继续上述循环.
2)这时说明有左括号和该右括号匹配,只需要stack.pop,并继续扫描下一个字符.
3)这时表示该左括号之前的所有括号都匹配了,同样计算匹配的长度是否比全局大.但是这里和1)不同的是,我们计算完之后继续将该左匹配压入栈,继续寻找
4) 说明该左括号和栈顶左括号之间的字符已经被匹配,计算匹配的长度是否比全局大,和3)类似.我们计算完之后继续将该左匹配压入栈,继续寻找
跳出循环有两种情况 第一种情况和扫描字符串结束.
如果是第一种情况,将开始扫描置为该点下一个,继续上述循环.
如果是第二种情况,需要判断一下stack是否为空,如果为空,那么说明从开始位置到最后都可以匹配,计算一下局部最大值是否为全局最大值.
如果不为空,说明栈顶括号的下一个到最后可以匹配,计算一下局部最大值是否为全局最大值. 程序结束.
最后程序只需要扫描一遍就可以找到最大值.
程序代码:
public int longestValidParentheses(String s) {
int[] stack=new int[s.length()];
char[] chs=s.toCharArray();
int length=0;
int i=0;
while(i<chs.length)
{
while(i<chs.length&&chs[i]==')')i++;//find the begin pos
int top=0;
int j=i+1;
stack[top++]=i;
while(j<chs.length)
{
if(chs[j]==')'&&top==0)//situation one
{
length=length<(j-i)?(j-i):length;
break;
}
else if(chs[j]==')'&&top!=0) //situation two
{
top--;
j++;
}else if(chs[j]=='(')
{
if(top==0)length=length<(j-i)?(j-i):length;//situation three
else length=length<(j-stack[top-1]-1)?(j-stack[top-1]-1):length;//situation four
stack[top++]=j;
j++;
}
}
if(top==0)length=length<(j-i)?(j-i):length;
else length=length<(j-stack[top-1]-1)?(j-stack[top-1]-1):length;
i=j+1;
}
return length;
}