题目:

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

  • push(x) -- Push element x onto stack.
  • pop() -- Removes the element on top of the stack.
  • top() -- Get the top element.
  • getMin() -- Retrieve the minimum element in the stack.

链接: http://leetcode.com/problems/min-stack/

题解:

最小栈。这道题在电面Bloomberg的supply chain组的Senior SDE时遇到了原题,秒杀掉了。然后面试的老印很坏,follow up说你这个不是stack, 说想要new stack<>()的时候自带min功能,跟我绕了半天,故意误导, 好恶心...最后果然电面没过-_____-!! 后来看了CC150, 才知道这老印也许想要的是CC150的写法 - MinStack extends Stack<Integer>, 然后用minStack和super进行互动,也是两个栈。

又聊远了,这道题目,保持stack的功能同时还要有getMin()。一般的方法是维护两个stack。 也可以维护一个stack,但要创建一个Node class,空间复杂度并不能被节省。 还有的做法是用一个stack,stack里存min到当前值x的距离,然后有些计算,比较巧妙。

维护两个stack, Time Complexity (pop,push,getMin,top) - O(1) , Space Complexity - O(n)。

class MinStack {
private Stack<Integer> stack = new Stack<>();
private Stack<Integer> minStack = new Stack<>(); public void push(int x) {
if(minStack.isEmpty() || x <= minStack.peek())
minStack.push(x);
stack.push(x);
} public void pop() {
if(stack.peek().equals(minStack.peek()))
minStack.pop();
stack.pop();
} public int top() {
return stack.peek();
} public int getMin() {
return minStack.peek();
}
}

维护一个栈,  Time Complexity (pop,push,getMin,top) - O(1) , Space Complexity - O(n)。

class MinStack {
private Stack<Node> stack; public MinStack() {
this.stack = new Stack<>();
} public void push(int x) {
int min = Math.min(x, getMin());
this.stack.push(new Node(x, min));
} public void pop() {
this.stack.pop();
} public int top() {
return this.stack.peek().val;
} public int getMin() {
if(this.stack.isEmpty())
return Integer.MAX_VALUE;
return this.stack.peek().min;
} private class Node {
public int min;
public int val; public Node(int val, int min) {
this.val = val;
this.min = min;
}
}
}

二刷:

除了维护两个栈的方法以外,还有两种方法, 一种是建立一个Node同时保存当前值和最小值。

另外一种是reeclapple的写法。

  1. 设定一个min,push的时候,除了第一个数外,只把每个数x和min的差值(x - min)存入栈。当 x< min的时候更新min = x
  2. pop的时候pop出这个差值,假如这个值小于0,我们更新min = min - pop,否则min不变
  3. 计算peek的时候,先peek出栈顶元素, 假如这个元素top大于0,那么返回  top + min, 否则返回min。这里理解比较tricky.
  4. 计算getMin的时候直接返回min

Java:

最简单的维护两个stack的。

class MinStack {
private Stack<Integer> minStack = new Stack<>();
private Stack<Integer> stack = new Stack<>(); public void push(int x) {
stack.push(x);
if (minStack.isEmpty() || x <= minStack.peek()) {
minStack.push(x);
}
} public void pop() {
int x = stack.pop();
if (x == minStack.peek()) {
minStack.pop();
}
} public int top() {
return stack.peek();
} public int getMin() {
return minStack.peek();
}
}

三刷:

要注意假如遇到的话,还要加上各种边界条件判断以及throw EmptyStackException

Java:

class MinStack {
private Stack<Integer> stack = new Stack<>();
private Stack<Integer> minStack = new Stack<>(); public void push(int x) {
stack.push(x);
if (minStack.isEmpty() || x <= minStack.peek()) minStack.push(x);
} public void pop() {
int x = stack.pop();
if (x == minStack.peek()) minStack.pop();
} public int top() {
return stack.peek();
} public int getMin() {
return minStack.peek();
}
}

使用一个Stack:

每次min要被更新的时候,先存入min,再存入新元素。相当于保持一个递减的min序列。  假如elements递减,则栈内元素类似 {min 1, elem1, min2, elem2, min3, elem3}等等,

  1. 这里在insert的时候,假如x <= min,则我们先把之前被更新过的min放进stack里, 把min设为当前的x, 之后把x放入栈
  2. 在pop的时候, 我们pop出一个元素,然后跟min比较,假如等于min,那说明下一个元素是旧的min,我们更新min为 stack.pop(), 也把这个旧的min pop出来
  3. top 直接返回 stack.peek();
  4. getMin直接返回min
class MinStack {
private Stack<Integer> stack = new Stack<>();
int min = Integer.MAX_VALUE; public void push(int x) {
if (x <= min) {
stack.push(min);
min = x;
}
stack.push(x);
} public void pop() {
int peek = stack.pop();
if (peek == min) min = stack.pop();
} public int top() {
return stack.peek();
} public int getMin() {
return min;
}
}

Update:

许多题目现在必须追求最优解了 -____-!!

public class MinStack {
private Stack<Integer> stack = new Stack<>();
private int min = Integer.MAX_VALUE /** initialize your data structure here. */
public MinStack() {
stack = new Stack<>();
} public void push(int x) {
if (x <= min) {
stack.push(min);
min = x;
}
stack.push(x);
} public void pop() {
int top = stack.pop();
if (top == min) min = stack.pop();
} public int top() {
return stack.peek();
} public int getMin() {
return min;
}
} /**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/

Reference:

http://www.geeksforgeeks.org/design-and-implement-special-stack-data-structure/

https://leetcode.com/discuss/21071/java-accepted-solution-using-one-stack

https://leetcode.com/discuss/15679/share-my-java-solution-with-only-one-stack

https://leetcode.com/discuss/19389/java-solution-accepted

https://leetcode.com/discuss/23927/smart-accepted-java-solution-linked-list

https://leetcode.com/discuss/16029/shortest-and-fastest-1-stack-and-2-stack-solutions

155. Min Stack的更多相关文章

  1. leetcode 155. Min Stack 、232. Implement Queue using Stacks 、225. Implement Stack using Queues

    155. Min Stack class MinStack { public: /** initialize your data structure here. */ MinStack() { } v ...

  2. leetcode 155. Min Stack --------- java

    Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...

  3. Java [Leetcode 155]Min Stack

    题目描述: Design a stack that supports push, pop, top, and retrieving the minimum element in constant ti ...

  4. Java for LeetCode 155 Min Stack

    Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...

  5. 【leetcode】155 - Min Stack

    Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...

  6. LeetCode题解 #155 Min Stack

    写一个栈,支持push pop top getMin 难就难在在要在常量时间内返回最小的元素. 一开始乱想了很多东西,想到了HashMap,treeMap,堆什么的,都被自己一一否决了. 后来想到其实 ...

  7. [LeetCode] 155. Min Stack 最小栈

    Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...

  8. LC 155 Min Stack

    问题描述 Design a stack that supports push, pop, top, and retrieving the minimum element in constant tim ...

  9. 【LeetCode】155. Min Stack 最小栈 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 栈同时保存当前值和最小值 辅助栈 同步栈 不同步栈 日期 题目地 ...

随机推荐

  1. Javascript中函数调用和this的关系

    例子先行: var myObject={ foo:"bar", func:function(){ var self=this; console.log("outerfun ...

  2. python学习第二天:数字与字符串转换及逻辑值

    1.数字与字符串的转化     #1.数字转字符,使用格式化字符串:         *1.demo = ‘%d’  %  source         *2.%d整型:%f 浮点型 :%e科学计数 ...

  3. javascript 正则 验证 第25节

    <html> <head> <title>Form对象</title> <script type="text/javascript&qu ...

  4. java异常练习2

    /*有一个圆形和长方形都可以获取面积,对于面积,如果出现非法数值,视为获取面积出现问题问题通过异常来表示.先要对这个程序进行基本的设置 *//*首先想一下,怎么写这个程序基本属性是肯定要的求面积呢?1 ...

  5. Wix: Using Patch Creation Properties - Minor Update

    Based on the project created in Wix: Using Patch Creation Properties - Small Update, Following chang ...

  6. Apache Shiro入门实例

    Shiro是一个强大灵活的开源安全框架,提供身份验证.授权.会话管理.密码体系. 1.先创建一个Maven项目 2.配置pom <project xmlns="http://maven ...

  7. js模拟苹果菜单

    模拟苹果菜单的js代码是从网上看到的,用来做导航菜单还是蛮好看的.这里借鉴一下. 效果描述:当鼠标移动离哪个图片最近的时候,这个图片最大,鼠标离的图片越远,则图片越小: 原理:主要用到了三角形的勾股定 ...

  8. WPF异步调用WCF服务

    wpf调用wcf时,第一次访问总耗时到达几秒,影响界面的用户体验,因此在wpf加载界面和加载数据时采用异步加载,即异步访问wcf服务, 由于是否采用异步加载和服务端无关,仅仅由客户端自己根据需要来选择 ...

  9. 使用phpize安装php模块

    1.下载包 2./usr/local/php/bin/phpize 3../configure --enable-soap  --with-php-config=/usr/local/php/bin/ ...

  10. hdu 5654 xiaoxin and his watermelon candy 树状数组维护区间唯一元组

    题目链接 题意:序列长度为n(1<= n <= 200,000)的序列,有Q(<=200,000)次区间查询,问区间[l,r]中有多少个不同的连续递增的三元组. 思路:连续三元组-& ...