01_设计一个有getMin功能的栈
01_设计一个有getMin功能的栈
【题目】
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。
【要求】
- pop、push、getMin操作的时间复杂度都是O(1)
- 设计的栈类型可以使用现成的栈结构
方法一:
【思路】我们使用两个栈,一个栈用来保存当前栈中的元素,其功能和一个正常的栈没有区别,这个栈记为 stackData;另一个栈用于保存每一步的最小值,这个栈记为 stackMin。具 体的实现方式有两种
(1)压入数据规则
假设当前数据为newNum,先将其压入stackData。然后判断 stackMin 是否为空:
- 如果为空,则 newNum 也压入 stackMin。
- 如果不为空,则比较 newNum 和 stackMin 的栈顶元素中哪一个更小;
- 如果 newNum 更小或两者相等,则 newNum 也压入 stackMin;
- 如果 stackMin 中栈顶元素小,则 stackMin 不压入任何内容。

(2)弹出数据规则 先在 stackData 中弹出栈顶元素,记为 value。然后比较当前 stackMin 的栈顶元素和 value 哪一个更小。 通过上文提到的压入规则可知,stackMin 中存在的元素是从栈底到栈顶逐渐变小的, stackMin 栈顶的元素既是 stackMin 栈的最小值,也是当前 stackData 栈的最小值。所以不会出现 value 比 stackMin 的栈顶元素更小的情况,value 只可能大于或等于 stackMin 的栈顶元素。 当 value 等于 stackMin 的栈顶元素时,stackMin 弹出栈顶元素;当 value 大于 stackMin 的栈 顶元素时,stackMin 不弹出栈顶元素,返回 value。 很明显可以看出,压入与弹出规则是对应的。
(3)查询当前栈中的最小值操作 由上文的压入数据规则和弹出数据规则可知,stackMin 始终记录着 stackData 中的最小值。 所以,stackMin 的栈顶元素始终是当前 stackData 中的最小值。
方案一的代码实现如 MyStack1 类所示:
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import java.util.Stack;
/**
* 1、设计一个有getMin功能的栈
*
* 【题目】
*
* 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。
*
* 【要求】
*
* 1. pop、push、getMin操作的时间复杂度都是O(1)
* 2. 设计的栈类型可以使用线成的栈结构
*/
public class MyStack1 {
private Stack<Integer> stackData;
private Stack<Integer> stackMin;
public MyStack1() {
this.stackData = new Stack<Integer>();
this.stackMin = new Stack<Integer>();
}
//压栈
public void push(int newNum) {
// 判断存放最小值的栈是否为空,不为空直接入栈
if (this.stackMin.isEmpty()) {
this.stackMin.push(newNum);
} else if (newNum <= this.getMin()) {
this.stackMin.push(newNum);
}
this.stackData.push(newNum);
}
public int pop() {
if (this.stackData.isEmpty()) {
throw new RuntimeException("栈中元素为空!");
}
int value = this.stackData.pop();
if (value == this.getMin()) {
this.stackMin.pop();
}
return value;
}
private int getMin() {
if (this.stackMin.isEmpty()) {
throw new RuntimeException("栈中元素为空!");
}
// Java利用Stack类的peek()函数获取堆栈中的顶部元素
return this.stackMin.peek();
}
}
本题对应于leetcode


对应于leetcode上的实现方式如下:
class MinStack {
Stack<Integer> stackData;
Stack<Integer> stackMin;
public MinStack() {
this.stackData = new Stack();
this.stackMin = new Stack();
}
// 将val元素压入栈
public void push(int val) {
// 1.1 存放最小值的栈stackMin是否为空,若为空则将当前元素压入栈
// 1.2 判断当前stackMin栈的栈顶元素与val大小,若当前val更小,则压入栈
if(stackMin.isEmpty() || stackMin.peek() >= val) {
stackMin.push(val);
}
stackData.push(val);
}
//删除堆栈栈顶元素
public void pop() {
// 这里stackMin出栈的情况主要是当stackData出栈的元素是栈最小值元素的情形
if (stackData.pop().equals(stackMin.peek())) {
this.stackMin.pop();
}
}
//获取堆栈顶部的元素
public int top() {
return this.stackData.peek();
}
// 获取堆栈的中的最小元素
public int getMin() {
return stackMin.peek();
}
}
方法二:
(1)压入数据规则
假设当前数据为newNum,先将其压入stackData。然后判断stackMin是否为空。如果为空,则newNum也压入stackMin;如果不为空,则比较newNum和stackMin的栈顶元素中哪一个更小。
如果newNum更小或者两者相等,则newNum也压入stackMin;如果stackMin中栈顶元素小,则把stackMin的栈顶元素重复压入stackMin,即在栈顶元素上再压入一个栈顶元素。

(2)弹出数据规则
在stackData中弹出数据,弹出的数据即为value;弹出stackMin中的栈顶,返回value。
(3)查询当前栈中的最小值操作
由于上文的压入数据规则和弹出数据规则可知,stackMin始终记录着stackData中的最小值,所以stackMin的栈顶元素始终是当前stackData中的最小值。
import java.util.Stack;
/**
* 1、设计一个有getMin功能的栈
*
* 【题目】
*
* 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。
*
* 【要求】
*
* 1. pop、push、getMin操作的时间复杂度都是O(1)
* 2. 设计的栈类型可以使用线成的栈结构
*/
// 方法二
public class MyStack2 {
//普通栈保存栈中的元素,功能和一个正常的栈没有区别
private Stack<Integer> stackData;
//保存每一步的最小值
private Stack<Integer> stackMin;
public MyStack2() {
this.stackData = new Stack<Integer>();
this.stackMin = new Stack<Integer>();
}
//压栈
public void push(int newNum) {
// 判断存放最小值的栈是否为空,不为空直接入栈
if (this.stackMin.isEmpty()) {
this.stackMin.push(newNum);
} else if (newNum < this.getMin()) { // 判断当前元素是否要入stackMin中,和stackMin的栈顶元素进行比较,若发现newNum更小则入栈,反之不入stackMin栈
this.stackMin.push(newNum);
} else {
this.stackMin.push(this.stackMin.peek());
}
// 所有的新元素都会入StackData栈
this.stackData.push(newNum);
}
//出栈
public int pop() {
// 判断栈中元素是否为空
if (this.stackData.isEmpty()) {
throw new RuntimeException("栈中元素为空!");
}
this.stackMin.pop();
return this.stackData.pop();
}
//获取stackMin栈中的栈顶元素,stackMin栈中保存的每一次入栈的最小值
private int getMin() {
if (this.stackMin.isEmpty()) {
throw new RuntimeException("栈中元素为空!");
}
// Java利用Stack类的peek()函数获取堆栈中的顶部元素
return this.stackMin.peek();
}
}
注意:方法一是更加好的方法
01_设计一个有getMin功能的栈的更多相关文章
- 算法与数据结构题目的 PHP 实现:栈和队列 设计一个有 getMin 功能的栈
刚入手了一本<程序员代码面试指南>,书中题目的代码都是 Java 实现的,琢磨着把这些代码用 PHP 敲一遍,加深印象. 题目:设计一个有 getMin 功能的栈 —— 实现一个特殊的栈, ...
- 设计一个有getMin功能的栈
[说明]: 本文是左程云老师所著的<程序员面试代码指南>第一章中“设计一个有getMin功能的栈”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解析说明 ...
- 《程序员代码面试指南》第一章 栈和队列 设计一个有getMin功能的栈
题目 实现一个特殊的栈,在实现栈的基本功能上,再实现返回栈中最小的元素的操作 要求 1. pop.push.getMin操作时间复杂度都是O(1) 2. 设计的栈类型可以使用现成的栈结构 java代码 ...
- 栈和队列----设计一个有getMin功能的栈
设计一个有getMin功能的栈 设计一个具有getMin功能的栈,可以返回栈中的最小的元素,可以使用现有的栈的数据结构,要求pop/push/getMin操作的时间复杂度是O(1). package ...
- 栈和队列问题:设计一个有 getMin 功能的栈
[知识点] 栈是一个先进后出(FILO-First In Last Out)的数据结构,队列是一种先进先出(FIFO-First In First Out)的数据结构. [题目] 实现一个特殊的栈,在 ...
- 设计一个有getMin功能的栈(2)
题目: 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. 要求: 1.pop.push.getMin操作的时间复杂度都是O(1) 2.设计的栈类型可以输用现成的栈结构 解答 ...
- 设计一个有getMin功能的栈(1)
题目: 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. 要求: 1.pop.push.getMin操作的时间复杂度都是O(1) 2.设计的栈类型可以输用现成的栈结构 解答 ...
- 常见面试算法题JS实现-设计一个有getMin功能的栈
前言: 已经确定工作了-下周一正式入职,按理说应该是可以好好浪荡一周的,但是内心总是不安,总觉得自己这个水平真的太菜了,还是趁着现在有自己的时间,赶紧多看看书,多学习学习吧orz所以把之前校招买的书, ...
- 左神算法书籍《程序员代码面试指南》——1_01设计一个有getMin功能的栈
[题目] 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. [要求] 1.pop.push.getMin操作的时间复杂度都是O(1).2.设计的栈类型可以使用现成的栈结构. ...
- 设计一个带有getmin功能的栈,保证时间复杂度在O(1)
2017-06-22 20:56:10 需要得到最小值,最简单的思路就是遍历一遍求出最小值.但是这样的时间复杂度会是O(n),不满足O(1)的要求.于是想到在建立一个栈来保存最小值. 具体操作是建立 ...
随机推荐
- SpringBoot CORS 跨域请求解决方案之配置过滤器
方式一:@CrossOrigin 方式二: @Configuration public class CorsConfig implements WebMvcConfigurer { @Override ...
- A Novel Cascade Binary Tagging Framework for Relational Triple Extraction(论文研读与复现)
A Novel Cascade Binary Tagging Framework for Relational Triple Extraction Zhepei Wei,Jianlin Su, Yue ...
- Linux磁盘专题-linux文件系统详解
这可是我几年前的杰作笔记呀.....当初手写计算都会,现在忘光光.... 物理硬盘Block的概念和作用 硬盘底层一次IO就是读.写一次扇区,一个扇区默认是512Byte. 读写大量文件如果以扇区为单 ...
- 中企网安信息科技:数据防泄密DLP管理系统概述
由华企网安总公司北京中企网安信息科技有限责任公司开发的<数据防泄密DLP管理系统>,获得国家版权局颁发的计算机软件著作权登记证书. 数据防泄密DLP管理系统是用于保护.监控和管理敏感数据的 ...
- 华企盾DSC邮件服务器测试连接提示Server has closed the connection(端口不对)
解决方法:邮件服务器端口填错了,应该是smtp.126.com:s465,或者smtp.126.com:s587 其他邮箱同理.
- MySQL面试题:一条SQL语句在MySQL中执行过程全解析
一 .MySQL 基础架构分析 介绍一下下图涉及的一些组件的基本作用帮助大家理解这幅图. 连接/线程处理(连接器): 身份认证和权限相关(如连接处理.授权认证.安全等等). 查询缓存: 执行查询语句的 ...
- 文心一言 VS 讯飞星火 VS chatgpt (144)-- 算法导论12.1 4题
四.用go语言,对于一棵有 n 个结点的树,请设计在 O(n)时间内完成的先序遍历算法和后序遍历算法. 我个人喜欢 灵小智 . 文心一言: 在 Go 语言中,我们可以使用递归来实现树的前序遍历和后序遍 ...
- 为啥JS/TS里都会有"use strict"
摘要:在日常JS/TS项目开发过程中,经常会在文件开头看到"use strcit"字样,这里的"使用严格"是什么意思? 本文分享自华为云社区<JS/TS里 ...
- Taro架构构析(2):Taro 设计思想及架构
从之前微信公众号的开发经验来说,以及腾讯开放平台的接入 等经验来看,一直对腾讯的开放文档 有心理阴影. 微信小程序从文件组织上看,一个小程序页面或组件,需要同时包含 4 个文件:脚本逻辑.样式.模板以 ...
- 直击火山引擎V-Tech峰会!仅需简单登录,即可极速体验数据引擎ByteHouse
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 9月19日,火山引擎"数据飞轮·V-Tech数据驱动科技峰会"在上海举办.会上重磅发布数智 ...