您的位置:首页 > Web前端

剑指Offer(Java版):包含min函数的栈

2016-07-22 00:00 225 查看
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度都是O(1).

看到这个问题,我们的第一反应可能是每次压入一个新元素进栈时,将栈里的所有元素排序,让最小的元素位于栈顶,这样就能在O(1)时间得到最小元素了。但这种思路不能保证最后压入的元素能够最先出栈,因此这个数据结构已经不是栈了。

我们接着想到在栈里添加一个成员变量存放最小的元素。每次压入一个新元素进栈的时候,如果该元素比当前最小的元素还要小,则更新最小元素。面试官听到这种思路之后就会问:如果当前最小的元素被弹出栈了,如何得到下一个最小的元素呢?

分析到这里我们发现仅仅添加一个成员变量存放最小元素是不够的,也就是说当最小元素弹出栈的时候,我们希望能够得到次小元素。因此在压入这个最小元素之前,我们要把次小元素保存起来。因此,在压入这个最小元素之前,我们要把次小元素保存起来。

是不是可以把每次的最小元素都保存起来,放在另外一个辅助栈里呢?我们不妨举几个例子来分析一下把元素压入或者弹出栈的过程。





题关键在于用辅助栈储存什么值。要保证辅助栈的top是最小值,pop之后的顶部仍然是最小值。也就是说辅助栈从上到下存储的应该是最小值->次小值->次次小值……

这里容易进入一个误区就是:难道辅助栈就是对数据栈的排序?如果真是这样,push的时候因为要排序不能满足O(1);数据栈pop的时候,辅助栈要先查找数据栈pop出去的值然后再pop,也不满足O(1)。

当两个栈为空时,push进去的第一个值即为最小值;

push第二个元素时,若push的值<辅助栈顶元素(此处即第一个值),则将此值压进辅助栈;若push的值大于等于辅助栈顶元素,则将辅助栈顶元素再次push进去。

pop的时候,数据栈辅助栈均弹出顶元素。

实现代码如下:

package cglib;

import java.util.Stack;

public class DeleteNode {
Stack<Integer> stack1 = new Stack<Integer>(); // 数据栈
Stack<Integer> stack2 = new Stack<Integer>(); // 辅助栈 用于返回min值

public void push(int node) {
stack1.push(node);
if (stack2.empty()) {
stack2.push(node);
} else {
if (node < stack2.peek().intValue())//如果进入的数小于辅助栈的栈顶元素
stack2.push(node);//则放进去进入的数
else stack2.push(stack2.peek());//否则放进辅助栈的栈顶元素
}

}

@SuppressWarnings("null")
public int pop() {

if(stack1.empty()||stack2.empty()){

return (Integer) null;
}
stack2.pop();
return stack1.pop();
}

public int top() {
if (!stack1.empty())
return stack1.peek().intValue();
else return 0;
}

public int min() {
if (!stack2.empty())
return stack2.peek().intValue();
else return 0;
}

public static void main(String[] args) {

DeleteNode ms = new DeleteNode();

ms.push(4);

ms.push(3);

ms.push(1);

ms.push(5);

ms.push(2);//4,3,1,5,2

//System.out.println("pop:" +ms.pop() );
System.out.println("min:" + ms.min() + " pop:" +ms.pop() );

System.out.println("min:" + ms.min() + " pop:" +ms.pop() );

System.out.println("min:" + ms.min() + " pop:" +ms.pop() );
System.out.println("min:" + ms.min() + " pop:" +ms.pop() );

}
}

输出:

min:1 pop:2
min:1 pop:5
min:1 pop:1
min:3 pop:3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: