JAVA栈相关习题3

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/

java 复制代码
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)

java 复制代码
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)

java 复制代码
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.最小栈

java 复制代码
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这个栈正常出栈,但是每次出栈的时候都要和最小栈的栈顶元素比较,如果一样,此时两个栈 都要出元素。

相关推荐
咩咩啃树皮7 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
灯澜忆梦8 小时前
GO_并发编程---定时器
开发语言·后端·golang
鱟鲥鳚8 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
-银雾鸢尾-8 小时前
C#中的StringBuilder相关方法
开发语言·c#
-银雾鸢尾-8 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
大模型码小白9 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
麻雀飞吧10 小时前
最新量化学习路径,交易认知和技术实现要并行
人工智能·python
腾渊信息科技公司10 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地11 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun31415911 小时前
TCP超时重传机制是为了解决什么问题?
java