1.将递归转化为循环
比如:逆序打印链表
// 递归方式void printList(Node head){if(null != head){printList(head.next);System.out.print(head.val + " ");}}
// 循环方式void printList(Node head){if(null==head){return;}Stack<Node> s=new Stack<>();
// 将链表中的结点保存在栈中Node cur=head;while(null!=cur){s.push(cur);cur=cur.next;}// 将栈中的元素出栈while(!s.empty()){System.out.print(s.pop().val+" ");}}
public void show3(ListNode head) {if(head == null) {return;}if(head.next == null) {System.out.println(head.val);return;}show3(head.next);System.out.println(head.val);}public void show4() {Stack<ListNode> stack = new Stack<>();ListNode cur = head;while (cur != null) {stack.push(cur);cur = cur.next;}//依次出栈while (!stack.empty()) {ListNode tmp = stack.pop();System.out.println(tmp.val);}}
2.括号匹配
(1)闭合顺序不对([)]
(2)左括号多了(()
(3)右括号多了())
结论:
1.当括号是匹配的时候,最终i遍历完了字符串,并且栈为空
2.遇到不匹配的就直接结束
3.当i遍历完了字符串,但是栈当中仍然有括号,则必定是左括号多了(肯定不匹配)
4.当栈空了,但是字符串还没有遍历完,则必定不匹配
思考:如何判断匹配
https://leetcode.cn/problems/valid-parentheses/description/
class Solution {public boolean isValid(String s) {Stack<Character> stack=new Stack<>();for(int i=0;i<s.length();i++){char ch=s.charAt(i);if(ch=='('||ch=='['||ch=='{'){//左括号入栈,因为左括号一定是符号最开始的部分stack.push(ch);}else{//是右括号的情况if(stack.empty()){return false;}else{char tmp=stack.peek();if((tmp=='('&&ch==')')||(tmp=='['&&ch==']')||(tmp=='{'&&ch=='}')){//括号匹配成功stack.pop();}else{return false;}}}}if(!stack.empty()){return false;}return true;} }
3.逆波兰表达式
150. 逆波兰表达式求值 - 力扣(LeetCode)
class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack=new Stack<>();for(String s:tokens){if(!isOpera(s)){//数字:放入栈当中stack.push(Integer.parseInt(s));//将字符串转成整数}else{//弹出栈顶的两个元素int num2=stack.pop();int num1=stack.pop();switch(s){case "+":stack.push(num1+num2);break;case "-":stack.push(num1-num2);break;case "*":stack.push(num1*num2);break;case "/":stack.push(num1/num2);break;}}}return stack.pop();}public boolean isOpera(String s){if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")){return true;}return false;}
}
4.栈的压入、弹出序列
1)何时入栈---每次都入
2)什么时候出栈
栈不为空的时候并且栈顶元素和k下标的元素相同时可以出栈
栈的压入、弹出序列_牛客题霸_牛客网 (nowcoder.com)
import java.util.*;public class Solution {public boolean IsPopOrder(int [] pushA,int [] popA) {Stack<Integer> stack = new Stack<>();int j = 0;//变量popA这个数组for (int i = 0; i < pushA.length; i++) {stack.push(pushA[i]);while (!stack.empty() && j < popA.length&& stack.peek() == popA[j]) {stack.pop();j++;}}return stack.empty();}
}
5.最小栈
import java.util.Stack;class MinStack {private Stack<Integer> stack ;private Stack<Integer> minStack ;public MinStack() {stack = new Stack<>();minStack = new Stack<>();}public void push(int val) {stack.push(val);//第一次在最小栈当中存储元素if(minStack.empty()) {minStack.push(val);}else {if(val <= minStack.peek()) {minStack.push(val);}}}public void pop() {//栈为空 则不能进行弹出元素if(stack.empty()) {return;}int val = stack.pop();if(val == minStack.peek()) {minStack.pop();}}//获取栈顶元素 和 最小栈没有关系public int top() {if(stack.empty()) {return -1;}return stack.peek();}//获取元素 不是删除元素public int getMin() {return minStack.peek();}}
1.入栈操作 stack正常入栈minStack 每次入栈的元素要和栈顶元素比较,如果比minStack 栈顶元素小,就要入栈。第一次入栈的时候,两个栈 都要放元素
2.出栈操作
stack这个栈正常出栈,但是每次出栈的时候都要和最小栈的栈顶元素比较,如果一样,此时两个栈 都要出元素。