码迷,mamicode.com
首页 > 其他好文 > 详细

Min Stack

时间:2015-04-15 16:44:16      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

https://leetcode.com/problems/min-stack/

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.

解题思路:

要求实现一个stack,和一般的stack唯一不同的是,要求能返回当前栈内的最小值。而且,关键是要求这个时间必须是O(1)的。

唉,暂时想不出,写一个O(n)的吧。居然也AC了。

class MinStack {
    Stack<Integer> stack = new Stack<Integer>();
    int min = Integer.MAX_VALUE;
    
    public void push(int x) {
        stack.push(x);
        if(x < min) {
            min = x;
        }
    }

    public void pop() {
        int temp = stack.pop();
        if(temp == min) {
            min = Integer.MAX_VALUE;
            for(Integer i : stack) {
                if(i < min) {
                    min = i;
                }
            }
        }
    }

    public int top() {
        return stack.peek();
    }

    public int getMin() {
        return min;
    }
}

但是这个解法肯定是不行的,要在O(1)时间内得到min,如果当前弹出的正是min,如何知道现在栈内剩余的最小值?

还是借鉴了大神的思路。因为本题要处理的数据结构是栈,栈的重要特点是FILO,先进后出。考虑当前最小值为min,那么在min后面进栈的大于min的值,都是会比min先出栈的。所以它们出栈对于当前栈的最小值根本没有影响,只要它们下面还有小于他们的数字。

借助上面的思想,我们要维护的其实是,这个min出栈后,它下面元素的最小值。

我们这里用一个minStack来保存这个“目前为止出现过的最小值”。如果目前进栈的数字比之前的最小数字还要小,或者等于(这里注意,一定要有等于),就将其塞进minStack。stack.pop()时,如果pop的数字等于minStack顶部,就将minStack也pop。

这样,每次弹出一个最小值,我们都能迅速知道剩下元素的最小值。弹出>min的值,minStack不动,因为对最小值根本没影响。塞进一个>min的值,minStack也不动,因为对“目前为止出现过的最小值”也没影响。塞进一个<=min的值,就将其也塞进minStack。因为“目前为止出现过的最小值”改变了。

代码如下:

class MinStack {
    Stack<Integer> stack = new Stack<Integer>();
    Stack<Integer> minStack = new Stack<Integer>();
    int min = Integer.MAX_VALUE;
    
    public void push(int x) {
        stack.push(x);
        // 这里<=是必须的,因为可能有两个min,否则minStack弹出一个,最小值就失去了
        if(minStack.empty() || x <= minStack.peek()) {
            minStack.push(x);
        }
    }

    public void pop() {
        int temp = stack.pop();
        if(temp == minStack.peek()) {
            minStack.pop();
        }
    }

    public int top() {
        return stack.peek();
    }

    public int getMin() {
        return minStack.peek();
    }
}

总结一下,一般而言,我们取得一个集合中的最小值,是要O(n)的时间。但是本题利用stack的特点,先进来的后出去。也就是说,如果大的数字比小的数字后进来,他的进出压根不会对当前min产生任何影响。这个性质,使得我们只要关注边界,就是push和pop最小值的操作就可以了。

这是一道非常好的题目,不复杂,但是很看思路,和对数据结构的理解。

Min Stack

标签:

原文地址:http://www.cnblogs.com/NickyYe/p/4428546.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!