leetcode#155. Min Stack

来源:互联网 发布:风水织梦网站源码 编辑:程序博客网 时间:2024/05/29 16:39

题目

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.
Example:

MinStack minStack = new MinStack();minStack.push(-2);minStack.push(0);minStack.push(-3);minStack.getMin();   --> Returns -3.minStack.pop();minStack.top();      --> Returns 0.minStack.getMin();   --> Returns -2.

思路

初始思路很偷懒,别的操作都好说,getmin的时候for循环查最短的元素。当然,会超时。看了下超时的用例,主要是一直在调用getmin,所以我将min的查询放到了push和pop中,getmin的时候直接return min。

代码

class MinStack(object):    stack = []    Min = False    Minindex = False    def __init__(self):        """        initialize your data structure here.        """        self.stack = []        self.Min = False        self.Minindex = False    def push(self, x):        """        :type x: int        :rtype: void        """        self.stack += [x]        if type(self.Min) == type(False) or self.Min > x:            self.Min = x            self.Minindex = len(self.stack) - 1    def pop(self):        """        :rtype: void        """        if self.stack:            self.stack = self.stack[:-1]            if not self.stack:                self.Min = False                self.Minindex = False            elif type(self.Minindex) != type(False) and self.Minindex == len(self.stack):                Min = self.stack[0]                minIndex = 0                for index, i in enumerate(self.stack):                    if Min > i:                        Min = i                        minIndex = index                self.Min = Min                self.Minindex = minIndex    def top(self):        """        :rtype: int        """        if self.stack:            return self.stack[-1]    def getMin(self):        """        :rtype: int        """        if self.stack:            return self.Min# Your MinStack object will be instantiated and called as such:# obj = MinStack()# obj.push(x)# obj.pop()# param_3 = obj.top()# param_4 = obj.getMin()

过是过了,但是最佳算法肯定不是这么搞的呀!遂看了下discussion,发现以下几个有趣的算法。

代码一(作者reeclapple)

public class MinStack {    long min;    Stack<Long> stack;    public MinStack(){        stack=new Stack<>();    }    public void push(int x) {        if (stack.isEmpty()){            stack.push(0L);            min=x;        }else{            stack.push(x-min);//Could be negative if min value needs to change            if (x<min) min=x;        }    }    public void pop() {        if (stack.isEmpty()) return;        long pop=stack.pop();        if (pop<0)  min=min-pop;//If negative, increase the min value    }    public int top() {        long top=stack.peek();        if (top>0){            return (int)(top+min);        }else{           return (int)(min);        }    }    public int getMin() {        return (int)min;    }}

这个算法的好处在于push的时候存x - min,如果结果小于0就更新min,pop的时候如果pop值小于0就更新min值,就可以恢复到除去pop值的min值。最后getmin的时候直接输出min值即可,不用遍历list

代码二(作者leftpeter2)

class MinStack{    static class Element    {        final int value;        final int min;        Element(final int value, final int min)        {            this.value = value;            this.min = min;        }    }    final Stack<Element> stack = new Stack<>();    public void push(int x) {        final int min = (stack.empty()) ? x : Math.min(stack.peek().min, x);        stack.push(new Element(x, min));    }    public void pop()    {        stack.pop();    }    public int top()    {        return stack.peek().value;    }    public int getMin()    {        return stack.peek().min;    }}

这个算法更精巧,完全不用计算。只需更改下存入的数据结构。如代码所示,该数据结构中带有min值,存入x的时候同时会将当前的min值存入。这样的好处是无论何时,栈顶元素的min值肯定是当前栈的min值,而当元素pop出去后也不用重新计算新的min值,因为除去pop的那个元素后当前的min值还在栈顶的min中。

代码三(作者sometimescrazy)

class MinStack {    int min = Integer.MAX_VALUE;    Stack<Integer> stack = new Stack<Integer>();    public void push(int x) {        // only push the old minimum value when the current         // minimum value changes after pushing the new value x        if(x <= min){                      stack.push(min);            min=x;        }        stack.push(x);    }    public void pop() {        // if pop operation could result in the changing of the current minimum value,         // pop twice and change the current minimum value to the last minimum value.        if(stack.pop() == min) min=stack.pop();    }    public int top() {        return stack.peek();    }    public int getMin() {        return min;    }}

这个答案也很不错,存x的时候如果要更新min值,就将min值也存入stack中,pop的时候如果pop值等于min,则min等于stack再次pop出来的值。总的来说就是min值更新的时候将之前的min值也存入stack中,pop的是min值时则恢复之前的min值。缺点就是最坏情况的时候空间占用会比较多。

总结

学到了3种有意思的算法,收获不少,以后也要每做一题都看看discussion学习学习。

原创粉丝点击