20. 有效的括号
典中典
需要注意过程中对stack是否为空的检查
以及最后不能直接返回true,而是要看stack是否为空来判断前后括号数量是否一致
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++){
if (s.charAt(i) == '(') stack.push(')');
else if (s.charAt(i) == '[') stack.push(']');
else if (s.charAt(i) == '{') stack.push('}');
else{
if (stack.isEmpty() || stack.peek() != s.charAt(i)) return false;
stack.pop();
}
}
return stack.isEmpty();
}
1047. 删除字符串中的所有相邻重复项
此题可以作为例子展示如何使用栈来连续删除重复项
尤其是去除一对重复项之后带来的两边重复问题
本质是对栈用来解决对称性问题的展示
public String removeDuplicates(String s) {
if (s == null || s.length() < 2) return s;
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++){
char ch = s.charAt(i);
if (!stack.isEmpty() && stack.peek() == ch) stack.pop();
else stack.push(ch);
}
StringBuilder sb = new StringBuilder();
while(!stack.isEmpty()){
sb.append(stack.pop());
}
return sb.reverse().toString();
}
150. 逆波兰表达式求值
主要的难点在于想到把每一步二元运算的结果作为一个值压栈
好处在于简化运算过程,不管什么运算符号,都只需要弹栈两个元素进行运算
需要注意对于减法和除法,因为不满足交换律,需要注意第二个弹栈的数为被减数/被除数
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for (String token: tokens){
if (!token.equals("+") && !token.equals("-") && !token.equals("*") && !token.equals("/"))
stack.push(Integer.valueOf(token));
else{
int a = stack.pop();
int b = stack.pop();
if (token.equals("+")) stack.push(b + a);
else if (token.equals("-")) stack.push(b - a);
else if (token.equals("*")) stack.push(b * a);
else if (token.equals("/")) stack.push(b / a);
}
}
return stack.peek();
}