给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
思路:
- 从左往右遍历
定义三个计数器
cnt : 统计当前未被抵消的’('的个数
max:统计遍历到当前位置为止,出现的最长有效括号对的个数
cur:统计当前已匹配上的有效括号对个数
遍历字符数组,更新cnt的值,
如果cnt>0,新增一个括号对,cur++;
如果cnt=0,新增一个括号对,cnt++,这时候可以更新max的值:max=max>cur?max:cur;
如果cnt<0,说明当前有效括号对统计结束,该进行下一次统计了,置零cnt和cur。
return max*2 - 从右往左遍历
定义三个计数器
cnt : 统计当前未被抵消的 ')'的个数
max:统计遍历到当前位置为止,出现的最长有效括号对的个数
cur:统计当前已匹配上的有效括号对个数
遍历字符数组,过程同上,不再赘述。
return max*2 - 最长有效括号对就是两次遍历返回值中,结果较大的那一个。
代码如下:
public int longestValidParentheses(String s) {
char[] chars = s.toCharArray();
int left = oneside('(',chars,0,chars.length,1);
int right = oneside(')',chars,chars.length-1,-1,-1);
return left>right?left:right;
}
private int oneside(char c, char[] chars, int start, int end, int add) {
int cnt = 0;
int max = 0;
int cur = 0;
for(int i=start;i!=end;i+=add){
if(chars[i]==c){
cnt++;
}else {
cnt--;
if(cnt>0){
// ( () 当前有个括号产生 但前面有多余的(
cur++;
}else if(cnt==0){
// () () 当前有个括号产生,且前面没有多余的(
cur++;
max = max>cur?max:cur; //如果不存在cnt=0的情况怎么办?比如 (() --那就从右往左遍历匹配')'
}else{
//到这个)为止,前面的最长有效括号统计完毕。。 各计数器需要清0,开始下一轮的计数
cnt = 0;
cur = 0;
}
}
}
return max*2;
}
说明:由于是在cnt==0这种情况下更新max的值,如果在遍历字符串的过程中不存在cnt=0这种情况,比如((),那不就完蛋了?解决办法就是,从右往左再遍历一次,以’)'为模板,统计匹配的括号对,在上述案例中,从右往左,必定存在cnt=0。