当前位置: 首页 > news >正文

【面试经典150 | 栈】最小栈

文章目录

  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 方法一:辅助栈
    • 方法二:一个栈
    • 方法三:栈中存放差值
  • 其他语言
    • python3
  • 写在最后

Tag

【设计类】【栈】


题目来源

155. 最小栈


题目解读

本题是一个设计类的题目,设计一个最小栈类 MinStack() 实现:

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

解题思路

方法一:辅助栈

维护两个栈,一个栈就是常规的栈 stk1,另一个栈 stk2 用来存放已经插入栈 stk1 中数字的最小值。

注意入栈和出栈操作时两个栈都要更新。

实现代码

class MinStack {public:MinStack() {min_stk.push(INT_MAX);}void push(int val) {stk.push(val);min_stk.push(std::min(min_stk.top(), val));}void pop() {stk.pop();min_stk.pop();}int top() {return stk.top();}int getMin() {return min_stk.top();}private:std::stack<int> stk;std::stack<int> min_stk;
};/*** 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();*/

复杂度分析

时间复杂度: O ( 1 ) O(1) O(1)

空间复杂度: O ( n ) O(n) O(n) n n n 为 操作次数。

方法二:一个栈

可以只使用一个栈来同时保存当前的最小值和 val

实现代码

class MinStack {
private:stack<pair<int, int>> stk;
public:MinStack() {stk.push(make_pair(INT_MAX, INT_MAX));}void push(int val) {stk.push({min(stk.top().first, val), val});}void pop() {stk.pop();}int top() {return stk.top().second;}int getMin() {return stk.top().first;}
};/*** 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();*/

复杂度分析

时间复杂度: O ( 1 ) O(1) O(1)

空间复杂度: O ( 1 ) O(1) O(1)

方法三:栈中存放差值

现在我们维护一个变量 minVal,表示当前插入的变量的最小值,栈中每次入栈的是 valminVal 的差值 differ。现在进行具体分析:

  • push(int val):如果此时栈为空,我们更新 minVal = val,向栈中插入 0;如果此时栈非空,首先向栈中插入 diff,根据 diff 的值来更新 minVal
    • 如果 diff > 0,说明插入的 val 大于当前的 minVal,则 minVal 不需要更新;
    • 否则表明插入的 val 小于或者等于当前的 minVal,则更新 minVal = val
  • pop():我们需要根据 diff 来更新弹出栈顶元素后的 minVal,具体地:
    • 先弹出栈顶元素 diff,并 pop
    • 如果 diff > 0,说明我们当时插入的 val 大于当时的 minVal,则 minVal 是不需要更新的;
    • 否则说明当时插入的 val 小于或者等于 minVal,当时的 minVal 是插入的 val,需要将 minVal 还原回去,即当时插入 val 更新 minVal 的过程如下,还原回去得到 minVal = minVal + diff

d i f f = v a l − m i n V a l ; m i n V a l = v a l ; diff = val - minVal; minVal = val; diff=valminVal;minVal=val;

  • top():如果 diff < 0,表示 minVal 就是最小栈的栈顶元素,否则 minVal + diff 才是最小栈的栈顶元素。
  • getMin():直接返回 minVal 即可。

实现代码

class MinStack {
private:stack<long long> stk;long long minVal, diff;
public:MinStack() {}void push(int val) {if (stk.empty()) {stk.push(0);minVal = val;}else {diff = val - minVal;stk.push(diff);minVal = diff > 0 ? minVal : val;}}void pop() {diff = stk.top();stk.pop();if (diff < 0) {minVal = minVal - diff;}}int top() {return stk.top() < 0 ? minVal : minVal + stk.top();}int getMin() {return minVal;}
};/*** 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();*/

复杂度分析

时间复杂度: O ( 1 ) O(1) O(1)

空间复杂度: O ( 1 ) O(1) O(1)


其他语言

python3

以下只给出方法三的 python3 代码,该方法比较巧妙,值得好好研究。

class MinStack:def __init__(self):"""initialize your data structure here."""self.stack = []def push(self, x: int) -> None:if not self.stack:self.stack.append(0)self.min_value = xelse:diff = x-self.min_valueself.stack.append(diff)self.min_value = self.min_value if diff > 0 else xdef pop(self) -> None:if self.stack:diff = self.stack.pop()if diff < 0:self.min_value = self.min_value - diffdef top(self) -> int:return self.min_value if self.stack[-1] < 0 else self.stack[-1] + self.min_valuedef getMin(self) -> int:return self.min_value if self.stack else -1

写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

相关文章:

【面试经典150 | 栈】最小栈

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;辅助栈方法二&#xff1a;一个栈方法三&#xff1a;栈中存放差值 其他语言python3 写在最后 Tag 【设计类】【栈】 题目来源 155. 最小栈 题目解读 本题是一个设计类的题目&#xff0c;设计一个最小栈类 MinStack() …...

Linux网络基础2 -- 应用层相关

一、协议 引例&#xff1a;编写一个网络版的计算器 1.1 约定方案&#xff1a;“序列化” 和 “反序列化” 方案一&#xff1a;客户端发送形如“11”的字符串&#xff0c;再去解析其中的数字和计算字符&#xff0c;并且设限&#xff08;如数字和运算符之间没有空格; 运算符只…...

【Python机器学习】零基础掌握SkewedChi2Sampler内核近似特征

有没有遇到这样的困扰:即使在拥有大量数据的条件下,传统的机器学习模型表现依然不佳?这时,数据预处理和特征工程成了解决问题的关键步骤。那么,有没有一种算法能够优化特征,提升模型性能呢? 假设一个在线商城希望通过用户行为(比如点击、购买等)来预测用户是否会成为…...

Unity Meta Quest 一体机开发(三):Oculus Integration 基本原理、概念与结构+玩家角色基本配置

文章目录 &#x1f4d5;教程说明&#x1f4d5;输入数据&#x1f4d5;Oculus Integration 处理手部数据的推荐流程&#x1f4d5;VR 中交互的基本概念&#x1f4d5;Oculus Integration 中的交互流程&#x1f4d5;配置一个基本的玩家物体⭐OVRCameraRig⭐OVRInteraction⭐OVRHandP…...

excel 拼接字符 单元格

需要将单元格作为字符串拼接&#xff0c;使用 & 符号&#xff0c;拼接逗号&#xff0c;分号&#xff0c;冒号&#xff0c;横杠等&#xff0c;需要用英文双引号。...

HarmonyOS 快速入门TypeScript

1.什么是TypeScript&#xff0c;它和JavaScript&#xff0c;ArkTs有什么区别 ArkTS是HarmonyOS优选的主力应用开发语言。它在TypeScript&#xff08;简称TS&#xff09;的基础上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等相应的能力&#xff0c;让开发…...

ChatGPT扩展系列之ChatExcel

文章目录 ChatGPT扩展系列之ChatExcel对某一列的文字进行处理对数据进行排序对数据进行计算微软官方又推出Excel AI插件ChatGPT扩展系列之ChatExcel 自从ChatGPT很空出世之后,很多基于ChatGPT的应用便如雨后春笋般应用而生,这些应用的底层本质就是利用了ChatGPT对自然语言的…...

AM@微元法和定积分的应用@平面图形面积@立体体积@曲线弧长

文章目录 abstract微元法平面图形的面积极坐标上图形面积曲边扇形面积 平行截面面积为已知的立体体积旋转体的体积绕 x x x轴旋转绕 y y y轴旋转另一类型旋转体积 曲线弧长参数方程表示的曲线弧长直角坐标方程表示的曲线弧长极坐标方程表示得曲线弧长小结 abstract 微元法定积…...

SparkStreaming【实例演示】

前言 1、环境准备 启动Zookeeper和Kafka集群导入依赖&#xff1a; <dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.12</artifactId><version>3.2.4</version></dependency><dependency>&l…...

提高抖音小店用户黏性和商品销量的有效策略

抖音小店是抖音平台上的电商模式&#xff0c;用户可以在抖音上购买各类商品。要提高用户黏性和商品销量&#xff0c;四川不若与众帮你整理了需要注意以下几个方面。 首先&#xff0c;提供优质的商品和服务。在抖音小店中&#xff0c;用户会通过观看商品展示视频和用户评价来选…...

提高公众意识:共同防范AI诈骗

随着人工智能技术的飞速发展&#xff0c;AI诈骗成为了一个不容忽视的威胁&#xff0c;影响到我们的社交、金融和个人隐私安全。在这个数字时代&#xff0c;提高公众对AI诈骗的意识至关重要&#xff0c;以下是一些关于如何提高公众意识以防范AI诈骗的观点&#xff1a; 认知AI诈…...

MES的物料管理

----物料管理的定义和作用---- 物料管理在制造执行系统&#xff08;MES&#xff09;中扮演着至关重要的角色。通过有效的物料管理&#xff0c;企业可以实现生产过程的高效性、准确性和可靠性&#xff0c;从而提高生产效率并降低成本。 一、物料管理的定义 物料管理是指对生产过…...

正点原子嵌入式linux驱动开发——Linux 多点电容触摸屏

随着智能手机的发展&#xff0c;电容触摸屏也得到了飞速的发展。相比电阻触摸屏&#xff0c;电容触摸屏有很多的优势&#xff0c;比如支持多点触控、不需要按压&#xff0c;只需要轻轻触摸就有反应。ALIENTEK的三款RGB LCD屏幕都支持多点电容触摸&#xff0c;本章就以ATK7016这…...

Git基础命令实践

文章目录 简介git的安装配置git的安装git的配置 git使用的基本流程创建版本库时光机穿梭版本回退工作区和暂存区管理修改撤销修改删除文件 远程仓库添加远程库从远程库克隆 总结 简介 本文主要记录了我在学习git操作的过程&#xff0c;以及如何使用GitHub。建议先参考廖雪峰的…...

微信小程序设计之页面文件pages

一、新建一个项目 首先&#xff0c;下载微信小程序开发工具&#xff0c;具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后&#xff0c;注册小程序账号&#xff0c;具体注册方法&#xff0c;可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…...

VScode 自定义主题各参数解析

参考链接&#xff1a; vscode自定义颜色时各个参数的作用(史上最全)vscode编辑器&#xff0c;自己喜欢的颜色 由于 VScode 搜索高亮是在是太不起眼了&#xff0c;根本看不到此时选中到哪个搜索匹配了&#xff0c;所以对此进行了配置&#xff0c;具体想增加更多可配置项可参考…...

Linux进程等待

文章目录 1. 为什么要进程等待2. 进程等待的方法waitwaitpid非阻塞轮询 1. 为什么要进程等待 子进程退出&#xff0c;如果父进程还未结束&#xff0c;没有管这个子进程&#xff0c;那么就可能会造成“僵尸进程”问题&#xff0c;进而出现内存泄漏 如果这个进程变成了“僵尸进程…...

python设计模式笔记1:创建型模式 工厂模式和抽象工厂模式

1.工厂模式 (1) 导入所需的模块&#xff08; json 和 ElementTree &#xff09;。 (2) 定义 JSON数据提取器类&#xff08; JSONDataExtractor &#xff09;。 (3) 定义 XML数据提取器类&#xff08; XMLDataExtractor &#xff09;。 (4) 添加工厂函数 dataextraction_factor…...

第五章 I/O管理 一、I/O设备的基本概念和分类

目录 一、什么是I/O设备 1、定义&#xff1a; 2、按特性分类&#xff1a; 3、按传输速率分类&#xff1a; 4、按信息交换的方式分类&#xff1a; 二、总结 一、什么是I/O设备 1、定义&#xff1a; I/O设备就是可以将数据输入到计算机&#xff0c;或者可以接收计算机输出…...

vue3动态引入图片(:src)

vite 官方默认的配置&#xff0c;如果资源文件在assets文件夹打包后会把图片名加上 hash值&#xff0c;但是直接通过 :src"imgSrc"方式引入并不会在打包的时候解析&#xff0c;导致开发环境可以正常引入&#xff0c;打包后却不能显示的问题 实际上我们不希望资源文…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...