【LeetCode】栈 - 20.有效的括号、150.逆波兰表达式求值、155.最小栈、栈的压入、弹出序列

Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
🌱🌱个人主页:奋斗的明志
🌱🌱所属专栏:数据结构

在这里插入图片描述

📚本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。

在这里插入图片描述

前言

  • 栈、虚拟机栈、栈帧有什么区别呢?
  • 栈 ---- 数据结构
  • 虚拟机栈 ---- JVM内存
  • 栈帧 ---- 调用方法的时候开辟的内存

一、有效的括号

1.题目


20.有效的括号


在这里插入图片描述


2.解析


在这里插入图片描述


3.代码展示


class Solution {
    //s为字符串
    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.isEmpty()){
                    return false;
                }
                //栈不为空
                //拿到栈顶元素
                //看是否匹配

                char tmp = stack.peek();
                if(tmp == '(' && ch == ')'){
                    stack.pop();
                }else if(tmp == '{' && ch == '}'){
                    stack.pop();
                }else if(tmp == '[' && ch == ']'){
                    stack.pop();
                }else{
                    return false;
                }
                
            }
        }

        //字符串遍历完了,栈不为空
        //例如: ( ( )
        if(!stack.isEmpty()){
            return false;
        }
        return true;
    }
}

二、逆波兰表达式求值


1.题目


150.逆波兰表达式求值


在这里插入图片描述


在这里插入图片描述


2.解析


在这里插入图片描述


【说明】

  • 对遍历的每个元素进行判断
  • 如果是数字进行压栈
  • 如果是运算符,依次从栈里面弹出两个元素
  • 进行相对应的运算符操作

主要方法 evalRPN 解析:

  • evalRPN 方法接收一个字符串数组 tokens,每个元素可以是操作数或运算符。
  • 创建一个 Stack 类型的栈 stack,用于存储操作数。
  • 遍历 tokens 数组,对每个元素进行判断:
  • 如果是操作数(通过 isOperation 方法判断是否为运算符),将其转换为整数并压入栈中。
  • 如果是运算符,从栈中弹出两个操作数(注意先弹出的是 num1,后弹出的是 num2,因为栈是先进后出的),根据运算符进行相应的运算,将结果压入栈中。
  • 最终,栈中剩余的唯一元素即为整个表达式的计算结果。

辅助方法 isOperation 解析:

  • isOperation 方法简单地判断字符串是否为 +、-、* 或 / 中的一个,用于区分操作数和运算符。

3.代码展示


class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        // 进行遍历
        for (int i = 0; i < tokens.length; i++) {
            String str = tokens[i];
            if (!isOperations(str)) {
                // 进行压栈操作
                // 将字符串转换为整形
                int val = Integer.valueOf(str);
                stack.push(val);
            } else {
                // 说明是运算符
                // 取出栈里面的最上面两个元素
                int num2 = stack.pop();
                int num1 = stack.pop();
                // 进行完 运算符操作后 结果进行压栈处理
                switch (str) {
                    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 isOperations(String str) {
        if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/")) {
            return true;
        }
        return false;
    }
}

三、栈的压入、弹出序列

1.题目


栈的压入、弹出序列


在这里插入图片描述


2.解析


  • j popV 数组的索引,用于遍历弹出顺序数组。
  • stack 是一个栈,用来模拟入栈和出栈操作。
  • 遍历 pushV 数组,依次将元素压入栈中。
  • 每次入栈后,通过一个 while 循环检查栈顶元素是否与当前 popV 数组指定的弹出顺序相符:
    • 如果栈顶元素与 popV[j] 相等,则执行出栈操作(即弹出栈顶元素),并将 j 向后移动一位。
    • 循环执行直到栈顶元素不再与 popV[j] 相等或者栈为空。
  • 这样可以模拟出栈的过程,检查是否能按照 popV 的顺序完整弹出。
  • 最终判断条件是 j 是否达到了 popV 数组的长度。如果达到了,说明所有的弹出操作都按照正确的顺序进行了,返回 true;否则返回 false。

3.代码展示


import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param pushV int整型一维数组
     * @param popV int整型一维数组
     * @return bool布尔型
     */
    public boolean IsPopOrder (int[] pushV, int[] popV) {
        // write code here
        int j = 0;
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < pushV.length; i++) {
            
            stack.push(pushV[i]);
            while (!stack.isEmpty() && j < popV.length && stack.peek() == popV[j]) {
                stack.pop();
                j++;
            }
        }
        return j >= popV.length;
    }
}

四、最小栈

1.题目


155.最小栈


在这里插入图片描述
在这里插入图片描述


2.解析

【注意】
要创建两个栈才能完成 在常数时间内检索


在这里插入图片描述


3.代码展示


class MinStack {
    // 定义两个栈
    // 一个正常存元素
    // 一个存最小的
    Stack<Integer> stack;
    Stack<Integer> minStack;

    public MinStack() {
        stack = new Stack<>();
        minStack = new Stack<>();
    }

    public void push(int val) {
        // 普通栈必须要放
        stack.push(val);
        // 最小栈,刚开始栈为空的时候也要放
        if (minStack.isEmpty()) {
            minStack.push(val);
        } else {
            if (val <= minStack.peek()) {
                minStack.push(val);
            }
        }
    }

    public void pop() {
        // 从普通栈 弹出
        int val = stack.pop();
        // 从最小栈 弹出
        if (val == minStack.peek()) {
            minStack.pop();
        }

    }

    public int top() {
        return stack.peek();

    }

    public int getMin() {
        return minStack.peek();
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(val);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

总结

在 Java 中,Integer.valueOf() Integer.parseInt() 都是用来将字符串转换为整数 (int) 的方法,但它们有一些区别:

返回类型:

  • Integer.valueOf(String str) 返回一个 Integer 对象。
  • Integer.parseInt(String str) 返回一个基本数据类型 int
String str = "123";
Integer valueOfResult = Integer.valueOf(str);  // 返回 Integer 对象
int parseIntResult = Integer.parseInt(str);   // 返回 int 值

缓存机制:

  • Integer.valueOf(String str) 方法内部使用了一个缓存机制,它会缓存整数值在 -128 到 127 范围内的对象实例。因此,对于这个范围内的整数,多次调用 valueOf() 方法会返回相同的对象实例,而不是每次都创建一个新对象。这可以提高性能并节省内存。
  • Integer.parseInt(String str) 方法则没有缓存机制,每次调用都会新建一个 int 类型的值。

异常处理:

  • Integer.valueOf(String str) 方法会抛出 NumberFormatException 异常,如果字符串无法转换为整数。
  • Integer.parseInt(String str) 也会抛出 NumberFormatException 异常,如果字符串无法转换为整数。

在这里插入图片描述
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值