思路:
- 括号匹配问题是栈的典型应用。在遍历的时候,每一个左括号(
(、{、[)都需要在右边找到与之匹配的右括号()、}、])才能称之为「有效」,所以看到左边括号的时候需要先「缓存」起来; - 分析特殊用例
[{()}]:先缓存的[反而是最后才能确定有与之匹配的],这样匹配的顺序符合「后进先出」的规律,因此考虑使用「栈」作为数据结构。
代码 1:
public class Solution {
public boolean isValid(String s) {
int len = s.length();
if (len == 0) {
return true;
}
if ((len % 2) == 1) {
return false;
}
char[] charArray = s.toCharArray();
Deque<Character> stack = new ArrayDeque<>();
for (char c:charArray) {
switch (c) {
case '(':
stack.addLast(')');
break;
case '[':
stack.addLast(']');
break;
case '{':
stack.addLast('}');
break;
default:
if (stack.isEmpty() || stack.removeLast() != c) {
return false;
}
break;
}
}
return stack.isEmpty();
}
}
复杂度分析
- 时间复杂度: , 是字符串 s 的长度;
- 空间复杂度:,最差情况下,字符串的一半字符字符要进入栈中
还可以把左右括号的匹配关系存在一个哈希表中,增加扩展性。
代码 2:
public class Solution {
public boolean isValid(String s) {
int len = s.length();
if (len == 0) {
return true;
}
// 奇数长度一定不是有效括号
if ((len % 2) == 1) {
return false;
}
char[] charArray = s.toCharArray();
Map<Character, Character> hashMap = new HashMap<>();
hashMap.put(')', '(');
hashMap.put(']', '[');
hashMap.put('}', '{');
Deque<Character> stack = new ArrayDeque<>();
for (char c : charArray) {
// 如果遍历到右括号,检查是否匹配
if (hashMap.containsKey(c)) {
// 栈为空和栈顶与当前不匹配都不能称之为"有效"
if (stack.isEmpty() || !hashMap.get(c).equals(stack.removeLast())) {
return false;
}
} else {
// 遍历到左括号就加入栈
stack.addLast(c);
}
}
return stack.isEmpty();
}
}
复杂度分析(同上)