给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
记录下自己的思路
通过不断的拆分,最终会拆分为以中心闭合的字符串
所以步骤如下
1、直接找到字符串的中心 对比相应位置上的括号是否是一对
2、判断相邻的两个字符串是否是一对括号,左括号奇数位,右括号偶数位。(其实可以使用拆分递归使其符合1,但这里考虑到比较特殊,则直接处理,避免不必要的递归)
3、如不是步骤1、2两种特殊情况,则取第一个括号,对比找到右括号(右括号出现的位置一定是),然后将两个括号中的字符截取,递归;
4、如果结果为false,则找下一个位置是否是预支匹配的右括号,如果是则执行步骤3,直到最后一位,如果都不存在则返回false
public boolean isValid(String s) {
//{[()]} 、{}[]()、{[]([])}
boolean res = false;
if (s==null||s.length() % 2 > 0) {
//字符串长度一定是2的整数倍
return res;
}
char[] chars = s.toCharArray();
//找到中心位置
int axle = s.length() / 2;
int stepSize = 0;
int left = axle - 1;
res = true;
while (res && left - stepSize >= 0) {
//默认结果设置为true,循环遍历 以中心对称的两个字符,直到left=0;
res = comparison(chars[left - stepSize], chars[axle + stepSize]);
stepSize++;
}
if (res) {
//如果为true ,则不用在遍历其他情况,因为其他情况一定为false
return res;
}
left = 0;
stepSize = 0;
axle = 1;
res = true;
while (res && axle + stepSize < s.length()) {
//默认结果设置为true,循环遍历 相邻的两个字符;
res = comparison(chars[left], chars[axle]);
left += 2;
axle += 2;
}
if (res) {
//如果为true ,则不用在遍历其他情况,因为其他情况一定为false
return res;
}
//不规则情况 {[]}()、{()[]}
//"[({(())}[()])]"
left = 0;
stepSize = 0;
axle = left + 1;//1 = 2^stepSize
while (axle < s.length()) {
//"(([])){}"
//从头开始找 对应的右括号一定出现在 奇数位
if (comparison(chars[left], chars[axle]) && (axle - left - 1) % 2 == 0) {
if (axle == s.length() - 1) {
//已经是最后一位
return res = isValid(s.substring(++left, axle));
} else {
res = isValid(s.substring(left+1, axle)) && isValid(s.substring(axle + 1));
if (res) {
return res;
} else {
axle += 2;
}
}
} else if (axle < s.length()) {
axle += 2;
} else {
return false;
}
}
return res;
}
private boolean comparison(char left, char right) {
boolean res = false;
if (left == '(' && right == ')') {
res = true;
} else if (left == '[' && right == ']') {
res = true;
} else if (left == '{' && right == '}') {
res = true;
}
return res;
}