问题描述:

  如何在O(1)时间复杂度获取栈中的最大值和最小值?

问题分析:

  普通栈规定的push(入栈)、pop(出栈)、peek(查看栈顶)等操作都只能在栈顶上操作,如果栈中元素是有序的,那么我们就可以记录栈顶和栈底元素完成问题要求,但这是不可能的。普通栈不能解决问题,显然我们需要重新定义一种新的栈结构。能否在栈中定义两个变量min和max记录最小值和最大值呢,答案是否定的,因为并不是只有进栈操作,经过一系列出栈操作后,有可能最开始的最大值和最小值已经出栈。为了解决这个问题,我们就需要两个辅助栈记录栈的每个状态下的最大值和最小值。

算法描述:

  定义一个minStack栈和一个maxStack栈,分别在栈顶保存当前栈内最小值和最大值,以minStack为例,每次有元素入栈,就与minStack的栈顶元素比较,若小于栈顶元素,则入栈成为新的栈顶元素,若大于栈顶元素,则入栈原先的栈顶元素,maxStack栈与上述思路相同。出栈时,三个栈都需要出栈。定义getMin与getMax函数分别返回minStack和maxStack栈顶元素,实现在O(1)时间复杂度获取栈中的最小值和最大值。

性能分析:

  时间复杂度:O(1)  

  空间复杂度:O(N)

  加入两个辅助栈实现O(1)时间复杂度获取栈中的最大值和最小值,典型的以空间换取时间。

代码实现:

// Java代码
class MyStack {
public void push(int e) {// 新建MyStack数据结构的push函数
stack.push(e);// 元素入栈
// 判断是否需要更新minStack栈顶元素
if (minStack.isEmpty() || e < minStack.peek()) {
minStack.push(e);// 入栈元素更小,更换栈顶元素
} else if (e >= minStack.peek()) {
minStack.push(minStack.peek());// 不用更换栈顶元素
} // 判断是否需要更新maxStack栈顶元素
if (maxStack.isEmpty() || e > maxStack.peek()) {
maxStack.push(e);// 入栈元素更大,更换栈顶元素
} else if (e <= maxStack.peek()) {
maxStack.push(maxStack.peek());// 不用更换栈顶元素
}
}
public int pop() {// 新建MyStack数据结构的pop函数
// 三栈全部出栈
int ret = stack.pop();
minStack.pop();
maxStack.pop();
return ret;
}
public int getMin() {// O(1)时间返回最小值
return minStack.peek();
}
public int getMax() {// O(1)时间返回最大值
return maxStack.peek();
} private Stack<Integer> stack = new Stack<>();// 存储栈
private Stack<Integer> minStack = new Stack<>();// 最小值辅助栈
private Stack<Integer> maxStack = new Stack<>();// 最大值辅助栈
}
// C++代码
class MyStack {
public:
void push(int e) {// 新建MyStack数据结构的push函数
stacks.push(e);// 元素入栈
// 判断是否需要更新minStack栈顶元素
if (minStack.empty() || e < minStack.top()) {
minStack.push(e);// 入栈元素更小,更换栈顶元素
} else if (e >= minStack.top()) {
minStack.push(minStack.top());// 不用更换栈顶元素
} // 判断是否需要更新maxStack栈顶元素
if (maxStack.empty() || e > maxStack.top()) {
maxStack.push(e);// 入栈元素更大,更换栈顶元素
} else if (e <= maxStack.top()) {
maxStack.push(maxStack.top());// 不用更换栈顶元素
}
}
void pop() {// 新建MyStack数据结构的pop函数
// 三栈全部出栈
stacks.pop();
minStack.pop();
maxStack.pop();
}
int top() {
return stacks.top();
}
int getMin() {// O(1)时间返回最小值
return minStack.top();
}
int getMax() {// O(1)时间返回最大值
return maxStack.top();
} private:
stack<int> stacks;// 存储栈
stack<int> minStack;// 最小值辅助栈
stack<int> maxStack;// 最大值辅助栈
};

如何在O(1)时间复杂度获取栈中最大值和最小值的更多相关文章

  1. js获取数组中最大值和最小值

    var max = Math.max.apply(null, 数组); 获取最大值 var min = Math.min.apply(null, 数组);获取最小值 一句话获取数组中最大的数,最小数

  2. JavaScript 获取数组中最大值、最小值

    笨方法 Array.prototype.max = function() { var max = this[0]; var len = this.length; for (var i = 1; i & ...

  3. js获取数组中最大值,最小值

    遍历方法 var arr =[12,14,34,566,34,98,77] var max = arr[0]; for(var i=0;i<arr.length;i++){ if(max< ...

  4. O(1)时间复杂度求栈中最小元素

    import java.util.Stack; /** * 功能:O(1)时间复杂度求栈中最小元素 * 思路:空间换取时间,使用两个栈,stack1栈存储数据,stack2栈存储最小值: * stac ...

  5. Javascript获取数组中最大和最小值

    取出数组中最大值或最小值是开发中常见的需求,今天继续讲解如何获取javascript数组中最大和最小值. 1.排序法 首先我们给数组进行排序,可以按照从小到大的顺序来排,排序之后的数组中第一个和最后一 ...

  6. JavaScript学习:取数组中最大值和最小值

    在实际业务中有的时候要取出数组中的最大值或最小值.但在数组中并没有提供arr.max()和arr.min()这样的方法.那么是不是可以通过别的方式实现类似这样的方法呢?那么今天我们就来整理取出数组中最 ...

  7. java基础编程——获取栈中的最小元素

    题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)).   题目代码 /** * Created by YuKai Fan on 2018/9 ...

  8. 转载——JavaScript学习笔记:取数组中最大值和最小值

    转载自:http://www.w3cplus.com/javascript/calculate-the-max-min-value-from-an-array.html. 取数组中最大值 可以先把思路 ...

  9. JavaScript 获取数组的最大值和最小值

    js获取数组最大值和最小值 使用apply方法: var a = [1,2,3,5]; console.log(Math.max.apply(null, a));//最大值 console.log(M ...

随机推荐

  1. Regular Expression & rgb2hex

    Regular Expression & rgb2hex regex // 颜色字符串转换 function rgb2hex(sRGB = 'rgb(255, 255, 255)') { co ...

  2. 如何使用 iMovie 去除视频里面的声音

    如何使用 iMovie 去除视频里面的声音 视频去除背景音 iMovie https://www.apple.com/imovie/ https://books.apple.com/book/id14 ...

  3. how to convert a number to a number array in javascript without convert number to a string

    how to convert a number to a number array in javascript without convert number to a string 如何在不将数字转换 ...

  4. uniapp 扫二维码跳转

    在h5和wxapp中 生成qrcode的组件 https://ext.dcloud.net.cn/plugin?id=39 wx小程序扫二位码文档 生成链接时 computed: { ...mapSt ...

  5. 死磕Spring之IoC篇 - 解析自定义标签(XML 文件)

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  6. SpringCloud(一):微服务架构概述

    1-1.  系统进化理论概述 在系统架构与设计的实践中,经历了两个阶段,一个阶段是早些年常见的集中式系统,一个阶段是近年来流行的分布式系统: 集中式系统: 集中式系统也叫单体应用,就是把所有的程序.功 ...

  7. Google单元测试框架gtest--值参数测试

    测试一个方法,需要较多个参数进行测试,比如最大值.最小值.异常值和正常值.这中间会有较多重复代码工作,而值参数测试就是避免这种重复性工作,并且不会损失测试的便利性和准确性. 如果测试一个函数,需要些各 ...

  8. (三)MySQL锁机制 + 事务

    转: (三)MySQL锁机制 + 事务 表锁(偏读) 偏向MyISAM存储引擎.开销小,加锁快,无死锁,锁定粒度大,发生锁冲突的概率最高,并发最低. 查看当前数据库中表的上锁情况,0表示未上锁. sh ...

  9. 用于功率集成电路应用的600伏、10安、4H-SIC横向单沟道金属氧化物半导体场效应晶体管的演示和分析

    用于功率集成电路应用的600伏.10安.4H-碳化硅横向单沟道金属氧化物半导体场效应晶体管的演示和分析 摘要: 本文报道了一个具有大电流处理能力(10 A)的600伏4H-碳化硅横向场效应晶体管的演示 ...

  10. kubernetes cpu限制参数说明

    docker CPU限制参数 Option Description --cpus=<value> Specify how much of the available CPU resourc ...