Cracking the coding interview--Q3.2
2014-02-05 18:01
381 查看
题目
原文:
How would you design a stack which, in addition to push and pop, also has a function min which returns the minimum element? Push, pop and min should all operate in O(1) time.
译文:
设计一个栈,除了push和pop方法外,还有一个min的函数能够返回最小的元素,并且push,pop,min的时间复杂度都为O(1)
解答
首先想到找出栈中最小元素,可以通过每push一个值就作比较,从而得出最小元素,但一旦最小元素在栈顶,执行了pop方法,最小元素出栈,那么就无法在O(1)的时间内找到最小值了,显然这种方法是不可行的。所以,可以考虑每一个元素维护一个指向从当前元素到栈底元素的最小值的指针,如下面例子:
![](https://img-blog.csdn.net/20140205180403703?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmF2eWlmYW5y/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
不过可以发现这样存储,浪费很多空间,因此,可以引入另外一个栈S,当每次入栈或者出栈的时候,都通这个额外栈的栈顶元素比较一下。入栈的时候,如果入栈元素大于S栈顶元素,S栈顶元素不变。否则,将入栈元素也压入到栈S中,使栈S保持一个局部的最小值;出栈的时候,如果出栈元素大于S栈顶元素,S栈顶元素不变。否则,将S栈的栈顶元素也一同出栈。
以下是利用LinkedList的栈结构来实现具有min()的栈的:
如有更好的方法,还望交流!
---EOF---
原文:
How would you design a stack which, in addition to push and pop, also has a function min which returns the minimum element? Push, pop and min should all operate in O(1) time.
译文:
设计一个栈,除了push和pop方法外,还有一个min的函数能够返回最小的元素,并且push,pop,min的时间复杂度都为O(1)
解答
首先想到找出栈中最小元素,可以通过每push一个值就作比较,从而得出最小元素,但一旦最小元素在栈顶,执行了pop方法,最小元素出栈,那么就无法在O(1)的时间内找到最小值了,显然这种方法是不可行的。所以,可以考虑每一个元素维护一个指向从当前元素到栈底元素的最小值的指针,如下面例子:
不过可以发现这样存储,浪费很多空间,因此,可以引入另外一个栈S,当每次入栈或者出栈的时候,都通这个额外栈的栈顶元素比较一下。入栈的时候,如果入栈元素大于S栈顶元素,S栈顶元素不变。否则,将入栈元素也压入到栈S中,使栈S保持一个局部的最小值;出栈的时候,如果出栈元素大于S栈顶元素,S栈顶元素不变。否则,将S栈的栈顶元素也一同出栈。
以下是利用LinkedList的栈结构来实现具有min()的栈的:
import java.util.*; class Q3_2{ public static void main(String[] args) { StackWithMin1 s1 = new StackWithMin1(); StackWithMin2 s2 = new StackWithMin2(); int[] arr = new int[]{6,3,4,6,9,1}; for(int i=0;i<arr.length;i++){ s1.push(arr[i]); s2.push(arr[i]); } System.out.println(s1.min()); System.out.println(s2.min()); s1.pop(); s2.pop(); System.out.println(s1.min()); System.out.println(s2.min()); } } class StackWithMin1{ LinkedList<Integer[]> values ; public StackWithMin1(){ values = new LinkedList<Integer[]>(); } public int pop(){ return values.pop()[0]; } public void push(int val){ //第一个元素入栈设置初始最小值 if(values.peek()==null){ values.push(new Integer[]{val,val}); } int min = values.peek()[1]; if(min<val){ values.push(new Integer[]{val,min}); }else{ values.push(new Integer[]{val,val}); } } public int min(){ int min = values.pop()[1]; return min; } } class StackWithMin2{ LinkedList<Integer> values; LinkedList<Integer> S;//额外栈 public StackWithMin2(){ values = new LinkedList<Integer>(); S = new LinkedList<Integer>(); } public void push(int val ){ Integer sPeek = S.peek(); values.push(val); if(sPeek==null||val<=sPeek){ S.push(val); } } public int pop(){ Integer t = values.pop(); if(t<=S.peek()){ S.pop(); } return t; } public int min(){ return S.peek(); } }
如有更好的方法,还望交流!
---EOF---
相关文章推荐
- 10种排序算法总结
- 时光荏苒,岁月静好-----2013年终总结
- hdu 变形课(简单搜索)
- Fedora 17及以前的版本关闭防火墙
- 为你加油!
- 部分HDU分类及解答
- 持续集成
- servlet操作数据库
- C++用new和不用new创建类对象区别
- Fedora关闭/禁用SELinux
- 学习java02
- 使用Project进行项目管理 - 项目管理系列文章
- UVa 120 煎饼堆
- 利用android proguard混淆代码
- 对象图(Object Diagram)—UML之图三
- 系统参数(v$system_parameter)有三种状态scope的使用以及生效
- c中 分层操作的实现
- C#中一些易混淆概念总结
- 排序算法
- C语言也可以“面向对象”—— C语言实现封装、继承和多态