题目:定义栈的数据结构,请在该类型中实现一个能够得到栈/队列的最小元素的min函数。在该栈/队列中,调用min、入栈(入队列)及出栈(出队列)函数的时间复杂度都是O(1)。

1. 包含min函数的栈

  看到这个问题,第一反应是创建一个成员变量保存栈中当前的最小元素。每次压入一个新元素进栈时,如果该元素比当前最小的元素还要小,则更新最小元素。采用这种思路,元素入栈的时候没有问题,但出栈时如果最小的元素被弹出栈了,就无法得到下一个最小的元素。如图,元素入栈出栈过程如下,当元素3出栈时,无法确定栈中当前最小元素4。

元素入栈出栈过程分析

  分析到这里,我们发现仅仅添加一个成员变量存放最小元素时不够的,也就是当最小元素被弹出栈的时候,我们希望能够得到次小元素。因此,在压入这个最小元素之前,需要把次小元素保存起来,于是采用一个“辅助栈”保存历史最小元素。还是以上面的入栈出栈为例,多了一个辅助栈,当元素3出栈时,依然可以的到栈的当前最小元素。

元素入栈出栈过程分析

算法的代码实现如下:

 import java.util.LinkedList;
import java.util.Stack; public class d30_MinInStack {
public static void main(String[] args) {
// 测试包含min函数的栈
StackWithMin<Integer> stack = new StackWithMin<>();
stack.push(3);
stack.push(4);
stack.push(2);
stack.pop(); // 当前最小元素出栈,则minStack最小元素也要出栈
stack.push(0);
stack.push(-1);
System.out.println(stack.dataStack); // [3, 4, 0, -1]
System.out.println(stack.minStack); // [3, 0, -1]
System.out.println(stack.min()); // -1
} /*
* 包含min函数的栈
*/
static class StackWithMin<T extends Comparable<T>> {
private Stack<T> dataStack; // 记录实际元素的栈
private Stack<T> minStack; // 记录最小元素的栈 public StackWithMin() {
this.dataStack = new Stack<>();
this.minStack = new Stack<>();
} /*
* 元素入栈
*/
public void push(T data) {
if (data == null) {
throw new RuntimeException("cannot push null");
}
if (dataStack.isEmpty()) {
dataStack.push(data);
minStack.push(data);
} else {
dataStack.push(data);
// 记录最小栈的当前最小元素
T curMin = minStack.peek();
// 新入栈函数小于curMin
if (data.compareTo(curMin) < 0) {
minStack.push(dataStack.peek());
}
}
} /*
* 元素出栈
*/
public T pop() {
if (dataStack.isEmpty()) {
throw new RuntimeException("dataStack is empty!");
}
// 如果出栈元素为dataStack栈的当前最小元素,minStack的栈顶元素出栈
if (dataStack.peek() == minStack.peek()) {
minStack.pop();
}
return dataStack.pop();
} /*
* 取栈中最小元素
*/
public T min() {
if (minStack.isEmpty()) {
throw new RuntimeException("minStack is empty!");
}
return minStack.peek();
}
}
}

2. 包含min函数的队列

  有了上面对栈的分析作为基础,实现包含min函数的队列就比较容易了。实现思路还是创建“辅助队列”,但与“辅助栈”不同的是,“辅助队列”并不是保存队列中历史最小元素。如果不是最小元素入队列,则“辅助队列”以递减的方式保存元素;如果是最小元素入队列,则“辅助队列”将其他元素出队,只保存该最小元素。具体的过程如下图所示:

元素入队出队过程分析

算法实现代码如下:

 import java.util.LinkedList;
import java.util.Stack; public class d30_MinInStack { public static void main(String[] args) {
// 测试包含min函数的队列
QueueWithMin<Integer> queue = new QueueWithMin<>();
queue.enqueue(3);
queue.enqueue(4);
queue.enqueue(7);
System.out.println(queue.min());
queue.enqueue(5);
System.out.println();
System.out.println(queue.min());
} /*
* 包含min函数的队列
*/
public static class QueueWithMin<T extends Comparable<T>> {
private LinkedList<T> dataQueue;
private LinkedList<T> minQueue; public QueueWithMin() {
dataQueue = new LinkedList<>();
minQueue = new LinkedList<>();
} // 元素入队
public void enqueue(T data) {
if (data == null) {
throw new RuntimeException("cannot enqueue null");
}
dataQueue.offer(data);
// 保证minQueue队列的元素递减
// 若data < 队头元素,则minQueue队头元素出队
while (!minQueue.isEmpty() && (data.compareTo(minQueue.peek()) < 0)) {
minQueue.poll();
}
// 若data < 队尾元素,则minQueue队尾元素出队
while(!minQueue.isEmpty() && (data.compareTo(minQueue.peekLast()) < 0)) {
minQueue.poll();
}
minQueue.offer(data);
} // 元素出队
public T dequeue() {
if (dataQueue.isEmpty()) {
throw new RuntimeException("dataQueue is empty!");
}
// dataQueue出队元素与minQueue队头元素相等,则minQueue队头元素出队
if (dataQueue.peek() == minQueue.peek()) {
minQueue.poll();
}
return dataQueue.poll();
} // 取队列最小元素
public T min() {
if (minQueue.isEmpty()) {
throw new RuntimeException("minQueue is empty!");
}
return minQueue.peek();
}
}
}

包含min函数的栈、队列的更多相关文章

  1. 剑指Offer面试题:19.包含Min函数的栈

    一.题目:包含Min函数的栈 题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数.在该栈中,调用min.push及pop的时间复杂度都是O(1). 这里我们要实现的就是min ...

  2. 【编程题目】设计包含 min 函数的栈

    2.设计包含 min 函数的栈(栈)定义栈的数据结构,要求添加一个 min 函数,能够得到栈的最小元素.要求函数 min.push 以及 pop 的时间复杂度都是 O(1). 我的思路: 用一个额外的 ...

  3. 【面试题021】包含min函数的栈

    [面试题021]包含min函数的栈  MinStack.cpp: 1234567891011121314151617181920212223242526272829303132333435363738 ...

  4. 面试经典-设计包含min函数的栈

    问题:设计包含min函数的栈(栈) 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素. 要求函数min.push以及pop的时间复杂度都是O(1). 解答:push 和pop的时间复杂度 ...

  5. 包含min函数的栈 ,二叉树的镜像

    包含min函数的栈 问题 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). 代码 # -*- coding:utf-8 -*- class Sol ...

  6. 算法: 包含min函数的栈

    * @Description 包含min函数的栈* @问题:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)).* @思路: 1:Stack 类中的p ...

  7. 《剑指offer》 包含min函数的栈

    本题来自<剑指offer> 包含min函数的栈 题目: 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). 思路: 举例子让抽象问题具体 ...

  8. 41. 包含min函数的栈

    包含min函数的栈 描述 设计一个支持push,pop,top等操作并且可以在O(1)时间内检索出最小元素的堆栈. push(x)–将元素x插入栈中 pop()–移除栈顶元素 top()–得到栈顶元素 ...

  9. 《剑指offer》第三十题(包含min函数的栈)

    // 面试题30:包含min函数的栈 // 题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min // 函数.在该栈中,调用min.push及pop的时间复杂度都是O(1). #i ...

随机推荐

  1. Java&Selenium 鼠标键盘及滚动条控制相关方法封装

    一.摘要 本片博文主要展示在使用Selenium with java做web自动化时,一些不得不模拟鼠标操作.模拟键盘操作和控制滚动条的java代码 二.模拟鼠标操作 package util; im ...

  2. 通过LVM备份mysql数据库脚本

    #!/bin/bash #******************************************************************** #encoding -*-utf8- ...

  3. CSS3 -- column 实现瀑布流布局

    本例使用 CSS column 实现瀑布流布局 关键点,column-count: 元素内容将被划分的最佳列数 关键点,break-inside: 避免在元素内部插入分页符 html div.g-co ...

  4. 洛谷P1080 国王游戏【大数】【贪心】

    题目:https://www.luogu.org/problemnew/show/P1080 题意: 一个国王和n个大臣,每个人左右手上都有一个数值. 现在将国王排在队首,将大臣进行排序.每个大臣的值 ...

  5. HDU 6102 - GCDispower | 2017 Multi-University Training Contest 6

    个人感觉题解的复杂度很玄,参不透,有没有大佬讲解一下- - /* HDU 6102 - GCDispower [ 数论,树状数组] | 2017 Multi-University Training C ...

  6. Maven手动将jar导入本地仓库

    1.使用cmd进入maven安装目录下的bin 2.运行mvn install:install-file -Dfile=jar包的路径 -DgroupId=gruopId中的内容 -Dartifact ...

  7. HDU 5863 cjj's string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )

    题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但 ...

  8. python 垃圾回收笔记

    目录 引用计数 python内部的引用计数机制 循环引用 调试内存泄漏 总结 python 程序在运行的时候,需要在内存中开辟出一块空间,用于存放运行时产生的临时变量:计算完成后,再将结果输出到永久性 ...

  9. jQuery系列(十一):jQuery的事件绑定和解绑

    1.绑定事件 语法: bind(type,data,fn) 描述:为每一个匹配元素的特定事件(像click)绑定一个事件处理器函数. 参数解释: type (String) : 事件类型 data ( ...

  10. Django Admin中增加导出Excel功能

    参考: https://www.cnblogs.com/yoyo008/p/9232805.html 在使用Django Admin时, 对于列表我们有时需要提供数据导出功能, 如下图: 在Djang ...