题目要求是在给定的一个包含左括号和右括号的字符串中,找出其最长的有效的子串使得左右括号匹配,并输出子串的长度。
我的思路是:从左向右扫描字符串,并统计左右括号的数目。如果右括号多于左括号,则说明从之前的有效位置到这里一定无法构成有效括号对,所以重新计数。如果左括号多于右括号,那么还有继续匹配的可能,继续扫描。如果相等,就把目前的长度记录下来。另外,在计数相等的时候有前面子串无效仅仅当前子串有效,如“)()”和相邻的前面子串仍然有效,如“()()”两种情况,所以我设置了consec这一变量来区分这两种情况,只要发现左右括号相等,就将它设为1,如果失效(右括号多于左括号),则重置为0。另外还有一点需要注意的是“((()”这种情况,如果仅仅从左向右采用以上方法扫描,那么到最后还是左>右,会输出0,我的策略是对这种情况将字符串反序,然后采用相同的策略,但是统计符号的时候反过来,即将上面策略的左右括号对换,将反序后的“)(”看做一对。正反序输出值取较大值输出。
代码如下:
class Solution {
public int longestValidParentheses(String s) {
int maxlen=0;
int sublen1=SubParentheses(s,'(',')');
String s2=new StringBuffer(s).reverse().toString();
int sublen2=SubParentheses(s2,')','(');
maxlen=Math.max(sublen1,sublen2);
return maxlen;
}
public int SubParentheses(String s, char a, char b) {
int left=0,right=0;
int len=0,consec=0,pre=0;
if (s.isEmpty()) return len;
for (int i=0;i<s.length();i++)
{
if (s.charAt(i)==a) left++;
else if (s.charAt(i)==b) right++;
if (right>left)
{
right=0;
left=0;
consec=0;
pre=0;
}
else if (left==right&&left!=0)
{
if (consec==1)
{
pre=pre+left;
if (pre>len) len=pre;
}
else
{
pre=left;
if(left>len) len=left;
}
right=0;
left=0;
consec=1;
}
}
return len*2;
}
}
另外这道题目应该可以采用dp解决,不过我是凭着对问题的直观感觉写的代码,并未考虑dp。