栈应用总结
-
栈的应用:非常适合用来做匹配消除元素类型的题
递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中
-
Java中栈的API
堆栈方法 等效Deque方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst()
20. 有效的括号
题目链接:代码随想录
-
解题思路:
①先分析出三种不匹配返回false的情况,分别是左多余,匹配不上,右多余,针对这几种情况做出应对
②技巧:如果当前匹配的是左符号元素,那么把右符号元素压入栈中。这样遍历到右符号元素的时候弹右元素出栈,不用将两种元素都放入栈。 -
图片解释:
public boolean isValid(String s) {
Deque<Character> deque = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(ch == '('){
deque.addFirst('(');
}else if(ch == '['){
deque.addFirst(']');
}else if(ch == '{'){
deque.addFirst('}');
}else if(deque.isEmpty()){//1.右元素多了
return false;
}else if(deque.peekFirst()!= ch){//2.没匹配上
return false;
}else{
//出栈
deque.removeFirst();
}
}
//3.判断左元素多没多
return deque.isEmpty();
}
1047. 删除字符串中的所有相邻重复项
题目链接:代码随想录
有效的括号 是匹配左右括号,本题是匹配相邻元素,最后都是做消除的操作。
- 解题思路:
这种涉及元素匹配的问题,适合用栈数据结构来存取和判断删除数据
①设置一个双向队列,遍历字符串,把不重复的字符压栈,重复的字符出栈,然后再遍历队列,再反转即可
public String removeDuplicates(String s) {
Deque<Character> deque = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(deque.isEmpty() || deque.peekFirst() != ch){//空是初始压入栈的情况
deque.addFirst(ch);
}else{
deque.removeFirst();//移除元素,并且不放入重复元素
}
}
StringBuilder builder = new StringBuilder();
while(!deque.isEmpty()){
builder.append(deque.removeFirst());
}
builder.reverse();
return builder.toString();
}
150. 逆波兰表达式求值
题目链接:代码随想录
- 解题思路:
①这道题其实只是解决给出一个后缀表达式如何计算出值,还有一种题目是如何把中缀表达式转换为后缀表达式
②解决方法:是操作符就弹出两个元素进行运算然后压栈;不是操作符就压栈
public int evalRPN(String[] tokens) {
Deque<Integer> deque = new LinkedList<>();
for (String s : tokens) {//这里不用记录下标,用这种方便
//判断字符串内容是否相等,用equals
if("+".equals(s)){
deque.addFirst(deque.removeFirst() + deque.removeFirst());
}else if("-".equals(s)){
deque.addFirst(-deque.removeFirst() + deque.removeFirst());
}else if("*".equals(s)){
deque.addFirst(deque.removeFirst() * deque.removeFirst());
}else if("/".equals(s)){
int b = deque.removeFirst();//除数
int a = deque.removeFirst();//被除数
deque.addFirst(a / b);
}else{
deque.addFirst(Integer.parseInt(s));
}
}
return deque.removeFirst();
}