一,问题描述

实现一个栈(元素遵守先入后出顺序),能够通过 min 方法在 O(1)时间内获取栈中的最小元素。同时,栈的基本操作:入栈(Push)、出栈(Pop),也是在O(1)时间内完成的。

二,问题分析

之所以认为这个问题有趣,是因为在实现 min 方法的过程 牵涉到了 “缓存一致性”问题。是不是听起来很高大上?哈哈,我臆想的。

思路1:添加一个成员变量总是保存当前栈中最小的元素。该思路的实现代码大致是这样的:

public class MinStack {

    private LinkedList<Integer> stack;
private int min;// save minimum ele of stack public int pop(){
//check pop minimum ele?
}
public void push(int ele){
//check push minimum ele?
}
public int getMin(){
return min;
}
}

这里就会存在一个问题:保存最小元素的 min 属性 与 栈中的最小元素不一致。

比如:当从栈中 pop 最小元素时,那 min 属性就要 保存 次最小元素了。那如何 找到次最小元素,然后赋值给 min 呢?

因此,问题的关键就是:当只使用一个 min 属性时,如何保证 min 属性 总是 保存的是当前栈中最小的元素?---即: min 代表的最小元素 要与 栈中的最小元素保存一致。一种方式是当pop出最小元素之后,再遍历栈找出次最小的元素,并将之赋值给 min 。但是,由于遍历使得时间复杂度不再是O(1)

思路2:

使用一个辅助栈。此方法能够实现在O(1)时间内获取栈中最小的元素,但是缺点是空间复杂度为O(N)

现在有两个栈:一个是保存元素的数据栈,另一个是辅助栈,辅助栈的栈顶总是 当前数据栈中最小的元素。当Push元素时,首先将该元素Push到数据栈,然后再将该元素与辅助栈的栈顶元素比较:如果该元素比辅助栈的栈顶元素小,则将该元素Push到辅助栈中;否则将辅助栈的栈顶元素再Push到辅助栈中。

比如,现在要Push的元素顺序如下:3,4,2,5....   在数据栈 和 辅助栈中保存的元素如下:

三,代码实现

代码中使用了 java.util.LinkedList 类作为 栈的实现。

import java.util.LinkedList;

public class MinStack {

    private LinkedList<Integer> dataStack;
private LinkedList<Integer> minStack; public MinStack() {
dataStack = new LinkedList<Integer>();
minStack = new LinkedList<Integer>();
} //base operation
public void push(int ele)
{
dataStack.push(ele);
if(minStack.size() == 0 || ele < minStack.peek())
minStack.push(ele);
else
minStack.push(minStack.peek());
} public Integer pop(){
if(dataStack.isEmpty())
return null; assert dataStack.isEmpty() == false && minStack.isEmpty() == false;
int ele = dataStack.pop();
minStack.pop();
return ele;
} public Integer min(){
if(minStack.isEmpty())
return null;
return minStack.peek();
} //hapjin test
public static void main(String[] args) {
MinStack stack = new MinStack(); int[] eles = {3,4,2,5};
for (int i : eles) {
stack.push(i);
}
System.out.println(stack.min());//
System.out.println(stack.pop());//
System.out.println(stack.pop());//
System.out.println(stack.min());//
stack.push(1);
System.out.println(stack.min());
}
}

实现一个 能在O(1)时间复杂度 完成 Push、Pop、Min操作的 栈的更多相关文章

  1. 数据结构---设计一个栈,push, pop, min 时间复杂度都是 O(1)

    普通的栈,push, pop 操作的复杂度是 O(1), 但是如果要找出其中的最小值,则需要 O(N)的时间. 题目要求 min 复杂度也是 O(1), 做法便是 空间换时间,每一步栈的最小值都用一个 ...

  2. php实现包含min函数的栈(这个题目用另外一个栈做单调栈的话时间复杂度会低很多)

    php实现包含min函数的栈(这个题目用另外一个栈做单调栈的话时间复杂度会低很多) 一.总结 这个题目用另外一个栈做单调栈的话时间复杂度会低很多 二.php实现包含min函数的栈 题目描述 定义栈的数 ...

  3. 面试题:对一个正整数n,算得到1需要的最少操作次数

    实现一个函数,对一个正整数n,算得到1需要的最少操作次数.操作规则为:如果n为偶数,将其除以2:如果n为奇数,可以加1或减1:一直处理下去.例子:func(7) = 4,可以证明最少需要4次运算n = ...

  4. Swift处理堆栈问题——给定两组序列,其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序

    题目:输入两个整数序列.其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序.为了简单起见,我们假设push 序列的任意两个整数都是不相等的.比如输入的push 序列是1. ...

  5. 无法更新 EntitySet“SoreInfo_Table”,因为它有一个 DefiningQuery,而 <ModificationFunctionMapping> 元素中没有支持当前操作的 <InsertFunction> 元素。

    无法更新 EntitySet"SoreInfo_Table",因为它有一个 DefiningQuery,而 <ModificationFunctionMapping> ...

  6. 无法更新 EntitySet“Ips_Articles”,因为它有一个 DefiningQuery,而 <ModificationFunctionMapping> 元素中没有支持当前操作的 <InsertFunction> 元素。

    今天我在使用ef的时候,发现了这样的报错. 无法更新 EntitySet“Ips_Articles”,因为它有一个 DefiningQuery,而 <ModificationFunctionMa ...

  7. DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢,而是说操作了这个对象后,会触发一些浏览器行为(转)

    一直都听说DOM很慢,要尽量少的去操作DOM,于是就想进一步去探究下为什么大家都会这样说,在网上学习了一些资料,这边整理出来. 首先,DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢 ...

  8. 无法更新 EntitySet“W_ReceiveData”,因为它有一个 DefiningQuery,而 <ModificationFunctionMapping> 元素中没有支持当前操作的 <InsertFunction> 元素。

    无法更新 EntitySet“W_ReceiveData”,因为它有一个 DefiningQuery,而 <ModificationFunctionMapping> 元素中没有支持当前操作 ...

  9. Codeforces Round #304 (Div. 2) B. Soldier and Badges【思维/给你一个序列,每次操作你可以对一个元素加1,问最少经过多少次操作,才能使所有元素互不相同】

    B. Soldier and Badges time limit per test 3 seconds memory limit per test 256 megabytes input standa ...

随机推荐

  1. Instant Radiosity实现

    本来说等把课程作业做完再来弄这个,但是还是没有忍住,先做了,主要原因还是这个算法很容易实现.这个算法在1997年由Keller首次提出.虽然名字叫Instant Radiosity,但是它和Radio ...

  2. js 时间相关函数

    实例: <!doctype html> <html> <head> <meta charset="utf-8"> <title ...

  3. Unable to load configuration. - Class: java.net.AbstractPlainSocketImpl

    [Bug笔记]Unable to load configuration. - Class: java.net.AbstractPlainSocketImpl 标签: bugjartomcat服务器互联 ...

  4. 深入理解IoC/DI

    ------------------------------------------------------------------------ 理解IoC/DI 1.控制反转 --> 谁控制谁 ...

  5. Dijkstra算法

    Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. /*图的邻接矩阵表示*/typedef ...

  6. Html限制input输入框只能输入数字

    限制输入框只能输入数字, onafterpaste防止用户从其它地方copy内容粘贴到输入框: <input type="text" onkeyup="this.v ...

  7. 删除Tomcat服务及其它注意

    使用sc delete Tomcat7(注意服务名是Tomcat7 不是Apache......Tomcat7.0). 绿色版无法启动的话,需要先ervice.bat install注册一下服务. 如 ...

  8. UI第十五节——UIWebView

    - (void)viewDidLoad {    [super viewDidLoad];    UIWebView *webView = [[UIWebView alloc] initWithFra ...

  9. python解析git log后生成页面显示git更新日志信息

    使用git log可以查到git上项目的更新日志. 如下两个git项目,我想把git的日志信息解析成一个便于在浏览器上查看的页面. https://github.com/gityf/lua https ...

  10. WebStrom快捷键

    WebStorm 是 JetBrains 推出的一款商业的 JavaScript 开发工具 任何一个编辑器都需要保存(ctrl + s),这是所有win平台上编辑类软件的特点,但是webstorm编辑 ...