每日刷题(四)

文章介绍了四道与栈数据结构相关的算法题目,包括逆波兰表达式求值、检查有效括号、判断栈的压入弹出序列以及实现带有最小值查询功能的栈。每道题目都提供了解题思路和Java代码实现,展示了栈在解决计算和验证问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一题:逆波兰表达式求值

给你一个字符串数组 tokens ,表示一个根据逆波兰表示法表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。

注意:

  • 有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。
  • 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
  • 两个整数之间的除法总是 向零截断 。
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。

示例 1:

输入:tokens = [“2”,“1”,“+”,“3”,“*”]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

输入:tokens = [“4”,“13”,“5”,“/”,“+”]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

示例 3:

输入:tokens = [“10”,“6”,“9”,“3”,“+”,“-11”,““,”/“,””,“17”,“+”,“5”,“+”]
输出:22
解释:该算式转化为常见的中缀算术表达式为:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

提示:

  • 1 <= tokens.length <= 104
  • tokens[i] 是一个算符(“+”、“-”、“*” 或 “/”),或是在范围 [-200, 200] 内的一个整数

解题思路:

  1. 构造isOperation方法判断字符串x是否为运算符
  2. 如果不是运算符,则将x转为int类型放到栈里
  3. 如果为运算符,stack弹出两个整数,判断为哪个运算符,并对两个整数进行相应的运算,最后返回stack弹出的整数

代码实现:

class Solution {
    private Boolean isOperation(String s) {
            if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")) {
                return true;
            }
            return false;
        }
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for(String x:tokens) {
            if(!isOperation(x)) {
                stack.push(Integer.parseInt(x));

            }else {
                int num2 = stack.pop();
                int num1 = stack.pop();
                switch(x) {
                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();
    }
}

第二题:有效的括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = “()”
输出:true

示例 2:

输入:s = “()[]{}”
输出:true

示例 3:

输入:s = “(]”
输出:false

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 ‘()[]{}’ 组成

解题思路:

  1. 遍历字符串,如果为左括号,则入栈
  2. 如果为右括号,则判断与栈顶元素是否匹配,若匹配,则出栈
  3. 字符串遍历完之后,如果栈为空,则左右括号匹配

代码实现:

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;
               }
               char top = stack.peek();
               if((top == '('&&ch == ')')||(top == '['&&ch == ']')||(top == '{'&&ch == '}')) {
                   stack.pop();
               }else {
                   return false;
               }    
            }
        }
        if(!stack.empty()) {
            return false;
        }
        return true;

    }
}

第三题:栈的压入、弹出序列

描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

  1. 0<=pushV.length == popV.length <=1000
  2. -1000<=pushV[i]<=1000
  3. pushV 的所有数字均不相同

示例1

输入: [1,2,3,4,5],[4,5,3,2,1]
返回值: true
说明:可以通过push(1)=>push(2)=>push(3)=>push(4)=>pop()=>push(5)=>pop()=>pop()=>pop()=>pop()
这样的顺序得到[4,5,3,2,1]这个序列,返回true

示例2

输入: [1,2,3,4,5],[4,3,5,1,2]
返回值: false
说明:由于是[1,2,3,4,5]的压入顺序,[4,3,5,1,2]的弹出顺序,要求4,3,5必须在1,2前压入,且1,2不能弹出,但是这样压入的顺序,1又不能在2之前弹出,所以无法形成的,返回false

解题思路:

  1. 用栈接收pushed里的元素,判断栈顶元素与popped数组j下标的元素是否相等
  2. 若相等,则弹出栈顶元素,j++,若不相等,则继续往栈里放元素
  3. 循环结束后,返回stack.empty()

代码实现:

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> stack = new Stack<>();
        int j = 0;
        for(int i = 0;i < pushed.length;i++) {
            stack.push(pushed[i]);
            while(j < popped.length&&!stack.empty()&&stack.peek() == popped[j]) {
                stack.pop();
                j++;
            }
        }
        return stack.empty();
    }
}

第四题:最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。

示例 1:

输入: [“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”] [[],[-2],[0],[-3],[],[],[],[]]
输出: [null,null,null,null,-3,null,0,-2]

解释: MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.

提示:

  • -231 <= val <= 231 - 1
  • pop、top 和 getMin 操作总是在 非空栈 上调用
  • push, pop, top, and getMin最多被调用 3 * 104 次

解题思路:

  1. 用两个栈stack,minStack实现最小栈
  2. 入栈操作时,将元素放入stack中,如果minStack为空,则将元素放入minStack中,若不为空,判断元素值是否小于等于minStack栈顶值,如果小于或等于,则将元素放入minStack
  3. 出栈操作时,先判断stack是否为空,判断stack弹出元素值与minStack栈顶元素值是否相等,若相等,则弹出minStack栈顶元素
  4. 获取栈顶元素时,先判断stack是否为空,然后获取stack栈顶元素值
  5. 获取栈最小元素时,先判断minStack是否为空,然后获取minStack栈顶元素值

代码实现:

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(minStack.peek() >= val) {
                minStack.push(val);
            }
        }
    }
    
    public void pop() {
        if(stack.empty()) {
            return;
        }
        int x = stack.pop();
        if(x == minStack.peek()) {
            minStack.pop();
        }
    }
    
    public int top() {
        if(stack.empty()) {
            return -1;
        }
        return stack.peek();
    }
    
    public int getMin() {
         if(minStack.empty()) {
            return -1;
        }
        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();
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值