LeetCode 20.有效的括号
LeetCode 一道简单的不能再简单的题了
题目描述
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true
示例 3:
输入: "(]"
输出: false
示例 4:
输入: "([)]"
输出: false
示例 5:
输入: "{[]}"
输出: true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
错误解法
很简单一道题,但我还是做错了。。。
class Solution {
public static boolean isValid(String s) {
Stack<Character> stack = new Stack();
for (char c : s.toCharArray()) {
if (c == '}') {// 右括号和栈顶判断,如果匹配继续判断,如果不匹配返回false
if (stack.pop() == '{') {
continue;
} else {
return false;
}
} else if (c == ')') {
if (stack.pop() == '(') {
continue;
} else {
return false;
}
} else if (c == ']') {
if (stack.pop() == '[') {
continue;
} else {
return false;
}
} else {// 左括号全部入栈
stack.push(c);
}
}
return stack.isEmpty();// 如果栈不为空(false),说明有未匹配的左括号
}
}
我的错误很明显,stack有可能为空,这时候用pop()
判断栈中内容就会抛异常,不是没有想到这个问题,但考虑这个问题后就会造成代码非常冗余。以侥幸的心理提交了一下,果不其然没通过,倒不如说通过了反而会怀疑用例的质量。
正确解法
所以这道题非常简单,但如何把代码写简洁难到了我这个算法初学者。最后在题解中看到一个解法。
class Solution {
public static boolean isValid(String s) {
Stack<Character> stack = new Stack();
for (char c : s.toCharArray()) {
if (c == '(') {// 遇到左括号让预期的右括号入栈
stack.push(')');
} else if (c == '[') {
stack.push(']');
} else if (c == '{') {
stack.push('}');
} else if (stack.isEmpty() || c != stack.pop()) {// 遇到右括号和栈顶的右括号预期比较
return false;
}
}
return stack.isEmpty();// 如果栈不为空(false),说明还有左括号没找到预期的匹配
}
}
栈的作用从记录历史变成记录预期,所以栈为空这种可能只需要在预期那里判断一次而不需要在每个条件处判断。
思路都是一样的,复杂度也都是O(n),但是代码就会简洁许多。这其实就相当于两种解法了。
算法的作用不仅仅是优化时间和空间,更易于阅读与理解的代码也应该是算法的意义之一。