有效的括号
题目描述
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: “()”
输出: true
示例 2:
输入: “()[]{}”
输出: true
示例 3:
输入: “(]”
输出: false
示例 4:
输入: “([)]”
输出: false
示例 5:
输入: “{[]}”
输出: true
思路
这题相当于设计编译器的一个小插件,检查大括号、中括号、小括号使用的合法与否。
从以下两个方面来判断。
1.字符串长度的奇偶性。若字符串的总长度为奇数,说明至少有一个括号没有配对。
2.通过第一个判断关卡后,我们要判断每个左半括号有没有一个右半括号与之匹配,同时还得注意每组括号只能是包含与被包含的关系,不能相交,如“({)}”是不合法的。所以,为了筛除两组或多组括号出现相交的情况,我加了一个辅助判断:匹配的两个半括号之间的半括号数必须为偶数或0(0是不是偶数呢?)。
为了方便处理,我将6种半括号转换成了3对互补的整数。
for(int i = 0; i < s.length(); i++) {
switch(s.charAt(i)) {
case '(':
hash[i] = 1; break;
case '[':
hash[i] = 2; break;
case '{':
hash[i] = 3; break;
case ')':
hash[i] = -1; break;
case ']':
hash[i] = -2; break;
case '}':
hash[i] = -3; break;
}
}
完整代码
class Solution {
public boolean isValid(String s) {
if(s.length() % 2 == 1) return false;
int[] hash = new int[s.length()];
for(int i = 0; i < s.length(); i++) {
switch(s.charAt(i)) {
case '(':
hash[i] = 1; break;
case '[':
hash[i] = 2; break;
case '{':
hash[i] = 3; break;
case ')':
hash[i] = -1; break;
case ']':
hash[i] = -2; break;
case '}':
hash[i] = -3; break;
}
}
int key = 1, step = 1;
for(int i = 0; i < s.length() - 1; i++) {
if(hash[i] == 4) continue;
step = 0;
for(int j = i + 1; j < s.length(); j++) {
if(hash[i] + hash[j] == 0 && (j - i) % 2 == 1) {
hash[j] = 4; //匹配后右半括号从序列中注销
step = 1;
break;
}
}
key *= step;
}
return key == 1;
}
}