20. 有效的括号
思路:用栈来模拟,分出三种不匹配的情况:
- 左括号多了;
- 最临近的左右括号不匹配;
- 右括号多了。
针对这三种情况做出对应的判断即可。
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Stack;
public class is_Valid {
public boolean isValid(String s) {
if (s.length() % 2 != 0) return false;
// Stack<Character> stack = new Stack<Character>();
Deque<Character> deque = new ArrayDeque<>();
char ch;
for (int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
if (ch == '(') {
deque.push(')');
} else if (ch == '[') {
deque.push(']');
} else if (ch == '{') {
deque.push('}');
} else if (deque.isEmpty() || ch != deque.peek()) { // 判断第3种和第2种情况
return false;
} else {
deque.pop(); // 如果是右括号判断是否和栈顶元素匹配
}
}
return deque.isEmpty(); // 判断第3种情况
}
}
1047. 删除字符串中的所有相邻重复项
力扣原题链接
栈的经典应用。
要知道栈为什么适合做这种类似于爱消除的操作,因为栈帮助我们记录了 遍历数组当前元素时候,前一个元素是什么。
思路1:使用 Deque 作为堆栈。
public String removeDuplicates(String s) {
// ArrayDeque会比LinkedList在除了删除元素这一点外会快一点
Deque<Character> stack = new ArrayDeque<>();
char ch;
for (int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
if (stack.isEmpty() || stack.peek() != ch) {
stack.push(ch);
} else {
stack.pop();
}
}
String str = "";
while (!stack.isEmpty()) {
str = stack.pop() + str;
}
return str;
}
思路2:拿字符串直接作为栈,省去了栈还要转为字符串的操作。
public String removeDuplicates(String s) {
StringBuilder res = new StringBuilder();
int top = -1; // top为 res 的长度
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
// 当 top > 0,即栈中有字符时,当前字符如果和栈中字符相等,弹出栈顶字符,同时 top--
if (top >= 0 && res.charAt(top) == ch) {
res.deleteCharAt(top);
top--;
} else { // 否则,将该字符 入栈,同时top++
res.append(ch);
top++;
}
}
return res.toString();
}
150. 逆波兰表达式求值
思路:逆波兰表达式为二叉树的后序遍历(左右中),声明一个 Integer 的栈,然后遍历给出的字符串数组,如遇运算符则弹出栈顶两元素做运算,其他情况就是遇到“数字”,这时 push 到栈里即可(记得将String 转换成 Integer),最后取出栈顶元素即为表达式的值。
public static int evalRPN(String[] tokens) {
Deque<Integer> stack = new ArrayDeque<>();
for (String token : tokens) { // leetcode 内置jdk的问题,不能使用==判断字符串是否相等
if (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")) {
int num2 = stack.pop();
int num1 = stack.pop();
if (token.equals("+")) stack.push(num1 + num2);
if (token.equals("-")) stack.push(num1 - num2);
if (token.equals("*")) stack.push(num1 * num2);
if (token.equals("/")) stack.push(num1 / num2);
} else {
// stack.push(Integer.valueOf(token));
stack.push(new Integer(token));
}
}
return stack.pop();
}