【刷题记录】stack queue的题目练习(上)

简介: 【刷题记录】stack queue的题目练习(上)

1. 最小栈


题目链接:155. 最小栈 - 力扣(LeetCode)

题干:

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

实现 MinStack 类:


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


示例:

输入:

[“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.


题目分析:


为了能够在O(1)的时间复杂度内找到当前栈中的最小值,我们能想到使用两个栈,一个栈正常存储数据(数据栈),另一个栈存储当前栈中的最小值(最小栈),这样最小值就能直接找到。


每次push数据的时候数据站正常push,最小栈判断在push之前的最小值与当前值的大小,如果push数据小于最小栈的top,那么最小栈就push当前值,否则就push栈顶值。

4277c1a91da1ab8486bdaae8c39fb1be.png

实际上,如果入栈的数据大多数都大于当前最小值时,最小栈中就会出现很多相同且连续的数,这样对于空间是很大的浪费,所以,我们可以考虑修改最小栈的入栈规则,只有当新入栈的数据小于当前最小值时才入最小栈,这样最小栈中的数据就不会出现这种冗余。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4feFqUnf-1682496626758)(null)]


代码实现:

//解法一:
class MinStack {
public:
    MinStack() {//这里默认构造函数就不用实现了,因为在这里成员变量会走初始化列表,在初始化列表这里会自动调用成员变量类型的默认构造函数
    }    
    void push(int val) {
        _st.push(val);
        if(_minst.empty() || val <= _minst.top())
        {
            _minst.push(val);
        }
    }    
    void pop() {
        if(_st.top() == _minst.top())
        {
            _minst.pop();
        }
        _st.pop();
    }   
    int top() {
        return _st.top();
    }
    int getMin() {
        return _minst.top();
    }
    stack<int> _st;
    stack<int> _minst;
};


976b8fb5f359962e59e627da9b98387b.png


2. 逆波兰表达式


题目链接:150. 逆波兰表达式求值 - 力扣(LeetCode)

题干:

给你一个字符串数组 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


题目分析:

对于逆波兰表达式的计算,我们按照顺序遍历的方式,找到第一个运算符,然后将前面两个操作数拿出来运算即可,按照这种方式,我们可以想到用栈来存放数据,遇到操作符就pop出两个元素用于运算

155cd411fdc487faffab1324d0cd7877.png

代码实现:

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for(auto& str : tokens)
        {
            if(str == "+" || str == "-" || str == "*" || str == "/")//遇到运算符
            {
                //拿到左右两个操作数
                int right = st.top();
                st.pop();
                int left = st.top();
                st.pop();
                switch(str[0])//判断是什么运算,然后将运算结果入栈
                {
                    case '+':
                        st.push(left + right);
                        break;
                    case '-':
                        st.push(left - right);
                        break;
                    case '*':
                        st.push(left * right);
                        break;
                    case '/':
                        st.push(left / right);
                        break;
                }
            }
            else//遇到数字
            {
                st.push(stoi(str));
            }
        }
        return st.top();
    }
};


12bc65f8f2a04a368cb5bd3b9708f0e7.png

拓展知识:中缀表达式和后缀表达式

表达式时由操作数和操作符组成的,我们一般见到的表达式通常是把操作符放在两个操作数之间的,这种把操作符放在中间的表达式叫做中缀表达式,这种表达式对人类很友好,但是对计算机不太友好。波兰数学家Jan Lukasiewicz提出了另一种数学表示法,它有两种表示形式:把运算符写在操作数之前,称为波兰表达式(Polish Expression)或前缀表达式(Prefix Expression),如+AB;把运算符写在操作数之后,称为逆波兰表达式(Reverse Polish Expression)或后缀表达式(Suffix Expression),如AB+。在上题中提到的逆波兰表达式就是后缀表达式


这里给出中缀转后缀的算法思路:


  1. 创建栈
  1. 从左向右顺序获取中缀表达式
  • 数字直接输出
  • 运算符
  • 情况一:遇到左括号直接入栈,遇到右括号将栈中左括号之后入栈的运算符全部弹栈输出,同时左括号出栈但是不输出。
  • 情况二:遇到乘号和除号直接入栈,直到遇到优先级比它更低的运算符,依次弹栈。
  • 情况三:遇到加号和减号,如果此时栈空,则直接入栈,否则,将栈中优先级高的运算符依次弹栈(注意:加号和减号属于同一个优先级,所以也依次弹栈)直到栈空或则遇到左括号为止,停止弹栈。(因为左括号要匹配右括号时才弹出)。
  • 情况四:获取完后,将栈中剩余的运算符号依次弹栈输出
相关文章
|
4天前
|
云安全 人工智能 自然语言处理
|
8天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
800 17
|
11天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
805 59
Meta SAM3开源:让图像分割,听懂你的话
|
2天前
|
人工智能 安全 小程序
阿里云无影云电脑是什么?最新收费价格个人版、企业版和商业版无影云电脑收费价格
阿里云无影云电脑是运行在云端的虚拟电脑,分企业版和个人版。企业版适用于办公、设计等场景,4核8G配置低至199元/年;个人版适合游戏、娱乐,黄金款14元/月起。支持多端接入,灵活按需使用。
236 164
|
9天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
336 116
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
368 3
|
6天前
|
弹性计算 搜索推荐 应用服务中间件
阿里云服务器租用价格:一年、1小时及一个月收费标准及优惠活动参考
阿里云服务器优惠汇总:轻量应用服务器200M带宽38元/年起,ECS云服务器2核2G 99元/年、2核4G 199元/年,4核16G 89元/月,8核32G 160元/月,香港轻量服务器25元/月起,支持按小时计费,新老用户同享,续费同价,限时秒杀低至1折。
406 166