大家好,我是魔笑,我们一起加油。
题目:
给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例1:
输入:s = "(()" 输出:2 解释:最长有效括号子串是 "()"
示例2:
输入:s = ")()())" 输出:4 解释:最长有效括号子串是 "()()"
示例3:
输入:s = "((()))()"
输出:8
解释:最长有效括号子串是 "((()))()"
题解:
1,当我们从左往右遍历时,我们计算左右括号的数量,当右括号( “)” )数大的时候,我们就将其舍弃,因为,之后无论是左括号还是右括号,都没法合成右效括号,我们就将左右括号清零。
2,以上面的条件看,我们始终是以做括号( "(" )开始,那么只要左阔号和右括号相等,那么肯定是有效括号,当右括号大时,那么肯定有效括号中断,那么我们就将所有舍弃,再找最长的有效括号,如:
3,还有一种情况,我们没法取得,就是,左括号一直大,所以我们得反方向再去找一遍,那么反向和正向互补,那么就能求得最终得有效括号,从左往右,不能相等,从右往左,两边括号数就能相等如图:
代码1:
/**
* leetcode第32题,最长有效括号
*/
public class Parentheses {
//有效括号的数量
private int max = 0;
//左括号数
private int right = 0;
//右括号数
private int left= 0;
public int longestValidParentheses7(String s) {
if (s.length() == 0) {
return 0;
}
String[] split = s.split("()");
int length = split.length;
//先从左往右遍历
for (int i = 0; i < length; i++) {
calculate1(split, i, 0);
}
left = 0;
right = 0;
//再从右往左遍历
for (int i = length - 1; i > 0; i--) {
calculate1(split, i, 1);
}
return max;
}
public void calculate1(String[] split, int i, int direction) {
if (split[i].equals("(")) {
left++;
} else {
right++;
}
//当左括号数和右括号数相等时(是有效括号),计算出有效的括号
if (left == right) {
max = max >= (left + right) ? max : (left + right);
}
//从左往右遍历是,当右括号数大时,舍弃,将状态重置。
//从右往左遍历是,当左括号数大时,舍弃,将状态重置。
switch (direction) {
case 0:
if (right > left) {right = 0;left = 0;}
break;
case 1:
if (left > right) {right = 0;left = 0;}
break;
default:
break;
}
}
}
代码2:
public class Parentheses {
//有效括号的数量
private int max = 0;
//左括号数
private int right = 0;
//右括号数
private int left= 0;
public int longestValidParentheses(String s) {
if (s.length() == 0) {
return 0;
}
String[] split = s.split("()");
int length = split.length;
int right= 0;
int left= 0;
//先从左往右遍历
calculate(split, 0,length, right, left, 0);
//再从右往左遍历
calculate(split, length-1,length, right, left, 1);
return max;
}
public void calculate(String[] split, int i,int length, int right, int left, int direction) {
if (split[i].equals("(")) {
left++;
} else {
right++;
}
当左括号数和右括号数相等时(是有效括号),计算出有效的括号
if (left == right) {
max = max >= (left + right) ? max : (left + right);
}
//从左往右遍历是,当右括号数大时,舍弃,将状态重置。
//从右往左遍历是,当左括号数大时,舍弃,将状态重置。
switch (direction) {
//从左往右遍历
case 0:
if (right > left) {right = 0;left = 0;}
break;
//从右往左遍历
case 1:
if (left > right) {right = 0;left = 0;}
break;
default:
break;
}
//从左往右遍历
if(direction==0&&i+1<length){
calculate(split, ++i,length, right, left, 0);
}
//从右往往遍历
if(direction==1&&i-1>=0){
calculate(split, --i,length, right, left, 1);
}
return;
}
}
如果对你有帮助,请给一个素质三连,谢谢