题目:
- 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值
学习内容:
20. 有效的括号
这道题实际上用的是栈匹配,如果遍历到左括号,就往栈里塞对应的右括号。如果还没遍历完栈就空了或者不匹配,那就返回fasle。如果匹配了,就把栈顶元素弹出。
class Solution {
public boolean isValid(String s) {
Deque<Character> stack = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '(') {
stack.push(')');
} else if (ch == '{') {
stack.push('}');
} else if (ch == '[') {
stack.push(']');
} else if (stack.isEmpty() || stack.peek() != ch) {
return false; // 遇到右括号,如果栈为空或者不匹配,返回false
} else {
stack.pop(); // 遇到右括号,且匹配,就弹出栈顶元素;
}
}
return stack.isEmpty(); // 如果是空就表示匹配,否则不匹配
}
}
时间复杂度:O(n)
空间复杂度:O(n)
1047. 删除字符串中的所有相邻重复项
class Solution {
public String removeDuplicates(String s) {
Deque<Character> stack = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (stack.isEmpty() || stack.peek() != ch) {
stack.push(ch); // 如果栈为空或者不匹配,就push
} else {
stack.pop(); // 如果匹配则弹出
}
}
String res = "";
while (!stack.isEmpty()) {
res = stack.pop() + res; // 注意这里res要放后面
}
return res;
}
}
时间复杂度:O(n)
空间复杂度:O(n)
150. 逆波兰表达式求值
核心:循环不变量(坚持一个规则到底,处理每一条边)
如:左闭右开,即处理一条边,处理第一个节点,但不处理最后一个节点。
class Solution {
public int evalRPN(String[] tokens) {
Deque<Integer> stack = new LinkedList<>();
for (int i = 0; i < tokens.length; i++) {
if ("+".equals(tokens[i])) {
stack.push(stack.pop() + stack.pop());
} else if ("-".equals(tokens[i])) {
stack.push(-stack.pop() + stack.pop()); // 这里要注意顺序
} else if ("*".equals(tokens[i])) {
stack.push(stack.pop()*stack.pop());
} else if ("/".equals(tokens[i])) {
int b = stack.pop();
int a = stack.pop();
stack.push(a/b); // 这里要注意顺序
} else {
stack.push(Integer.valueOf(tokens[i])); // 如果是数字字符,则转为数字后push进栈
}
}
return stack.pop();
}
}
时间复杂度:O(n)
空间复杂度:O(n)
总结
栈非常适合相邻字符之间消除与匹配类型的题目
学习时间:
2024.3.17