20. 有效的括号
思路
栈的先进后出特性适合解决对称匹配的问题,本题中的括号左右匹配就可以使用栈来辅助解决
解题思路
- 如果遇到左半边,则先把右半边存进去
- 如果队列不为空,且遇到了右半边,则直接对比栈顶元素是否和当前的右半边是否相等,不想等则false
- 如果匹配过程中或右半边匹配不上栈顶元素,则说明匹配失败
- 如果匹配完,队列不为空,说明左半边元素多了,返回false
复杂度
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)
代码
Java
class Solution {
public boolean isValid(String s) {
Deque<Character> deque = new LinkedList<>();
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(']');
}
// 如果队列不为空,且遇到了右半边,则直接对比栈顶元素是否和当前的右半边是否相等,不想等则false
else if (!deque.isEmpty() && deque.peek() == ch) {
deque.pop();
} else if (deque.isEmpty() || deque.peek() != ch) {
return false;
}
}
// 如果匹配完,队列不为空,说明左半边元素多了,返回false
return deque.isEmpty();
}
}
1047. 删除字符串中的所有相邻重复项
思路
利用栈 FIFO 的特性,可以对比字符串当前字符和前一个字符,如果相同,则栈顶弹出,同时当前字符也丢弃。最后栈里的字符就是结果
解题思路
注意:最后从栈中组装字符时,注意字符的顺序
复杂度
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)
代码
Java
class Solution {
public String removeDuplicates(String s) {
Deque<Character> deque = new LinkedList<>();
char ch;
for (int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
if (deque.isEmpty() || deque.peek() != ch) {
deque.push(ch);
} else {
deque.pop();
}
}
String result = "";
while (!deque.isEmpty()) {
result = deque.pop() + result;
}
return result;
}
}
150. 逆波兰表达式求值
思路
用栈来暂时存储运算值,结合当前指向的值,组成运算所需的左右值
解题思路
复杂度
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)
代码
Java
class Solution {
public int evalRPN(String[] tokens) {
Deque<String> deque = new LinkedList<>();
Integer left;
Integer right;
for (String token: tokens) {
if ("+".equals(token)) {
right = Integer.valueOf(deque.pop());
left = Integer.valueOf(deque.pop());
deque.push(String.valueOf(left + right));
} else if ("-".equals(token)) {
right = Integer.valueOf(deque.pop());
left = Integer.valueOf(deque.pop());
deque.push(String.valueOf(left - right));
} else if ("*".equals(token)) {
right = Integer.valueOf(deque.pop());
left = Integer.valueOf(deque.pop());
deque.push(String.valueOf(left * right));
} else if ("/".equals(token)) {
right = Integer.valueOf(deque.pop());
left = Integer.valueOf(deque.pop());
deque.push(String.valueOf(left / right));
} else {
deque.push(token);
}
}
return Integer.valueOf(deque.pop());
}
}