20. 有效的括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。
思想想象成消消乐,‘(’ 遇到 ‘)’,便会消除;如果括号个数不是偶数或者最后还有剩余括号,那么一定不是有效的;
栈
创建一个哈希表,键为右括号,值为左括号
遍历括号,左括号直接入栈,
如果是右括号,判断栈是否为空、反方向括号对应的值是不是栈顶元素
不为空&是栈顶元素,出栈
慢慢消除,最后栈为空,返回true
return stack.isEmpty();
注意不可以遍历完直接返回true,可能左括号多。
public boolean isValid(String s) {
int n = s.length();
if(n % 2 == 1){
return false;
}
Map<Character, Character> map = new HashMap<Character, Character>() {{
// 将 })] 作为key
put('}', '{');
put(']', '[');
put(')', '(');
}};
// 新建一个栈
LinkedList<Character> stack = new LinkedList<>();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
// 如果c是 })], 则判断, 否则说明是({[ , 直接入栈
if(map.containsKey(c)){
// stack.peek() 获取栈顶元素
//stack.peek() != map.get(c)),如果第一次出现反方向括号不是在中间的右面第一个,那么它一定与左边的(即栈顶元素)闭合
if(stack.isEmpty() || stack.peek() != map.get(c)){
return false;
}
// 将栈顶移除(先进后出,栈顶是最接近 c 的左括号)
stack.pop();
}else{
// 说明c是({[ , 直接入栈
stack.push(c);
}
}
return stack.isEmpty();
}
巧妙低效方法
消消乐想法的终极体现:
最多消除length/2次;循环消除,最后为空则有效
class Solution {
public boolean isValid(String s) {
int length = s.length() / 2;
if(length % 2 == 1){
return false;
}
//最多循环长度的一般,把如下规则的慢慢消除
for (int i = 0; i < length; i++) {
s = s.replace("()", "").replace("{}", "").replace("[]", "");
}
return s.length() == 0;
}
}