`

Leetcode - Min Stack

 
阅读更多
[分析]
这题属于简单题,之所以要记录下是因为遇到了个不理解的Java语法问题。
在pop()时如果判断条件写成if (minStack.peek() == stack.peek())是要吃WA的,
原因是在表达式中比较的是引用本身,而不是值,奇怪的是在main中我认为一样的情况(e\f这对)判断结果却不同。
在pop()中执行如下两句:
        System.out.println(minStack.peek() + " " + stack.peek());
        System.out.println(minStack.peek() == stack.peek());
第一行打印的是值本身,第二行即使相同值得到的是false,太诡异了。。。
[补充1]
yb君认为e\f和pop()中并不是一种情况,猜测e\f是常量,Java编译时对其进行了优化,使用同一个实例。java中确实有此机制——常量池,以后有时间可以查查编译后的字节码验证下。
从这题得到的教训就是:以后遇到Integer的比较要转为intValue(),这样最保险。

[补充2]
最近才发现leetcode 讨论区帖子可以查看most voted,以前在默认页肉眼搜most voted,服了自己。然后看到这道题目有多种仅适用一个栈的巧妙思路。列举如下:
思路1:最省空间的方案。使用一个栈+一个变量min,栈中保存的是每个元素同它入栈时min的差值x - min, x为入栈元素。push时若x < min,则更新min。pop 和 top时需要额外计算保证算法的正确性。pop出的元素若>=0,说明栈顶元素非最小值,不需要更新min,若 < 0,说明是当前栈中的最小值,更新min=min - pop()。top时若发现栈顶是正数,需返回peek() + min, 若是负数,直接返回min。https://leetcode.com/discuss/15679/share-my-java-solution-with-only-one-stack
思路2:比较清晰的方案,空间换时间。栈中保存元素是自定义的一个类,该类有两个属性,一个是当前元素,一个是当前最小值,不考虑栈本身所占空间,其空间复杂度比两个栈还高。https://leetcode.com/discuss/15679/share-my-java-solution-with-only-one-stack
思路3:比思路1容易理解,空间复杂度和两个栈一样。每次更新min时同时将老的min先入栈,这样每次pop出min时可再pop一个得到新的min。

class MinStack {
    LinkedList<Integer> stack = new LinkedList<Integer>();
    LinkedList<Integer> minStack = new LinkedList<Integer>();
    public void push(int x) {
//        if (minStack.isEmpty() || x <= minStack.peek()) // ok 
        if (minStack.isEmpty() || x <= getMin())  // ok & more safe
            minStack.push(x);
        stack.push(x);
    }

    public void pop() {
        if (stack.isEmpty()) return;
//         if (minStack.peek() == stack.peek()) { // Wrong Answer
        if (minStack.peek().intValue() == stack.peek().intValue()) // ok
        if (getMin() == stack.peek()) // ok & more safe
            minStack.pop();
        stack.pop();
    }

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

    public int getMin() {
        return minStack.peek();
    }
    
    public static void main(String[] args) {
        Integer a = 2;
        Integer b = 2;
        Integer c = new Integer(3);
        Integer d = new Integer(3);
        int e = 4;
        int f = 4;
        System.out.println(a == b);
        LinkedList<Integer> stack1 = new LinkedList<Integer>();
        LinkedList<Integer> stack2 = new LinkedList<Integer>();
        stack1.push(1);
        stack2.push(1);
        System.out.println(stack1.peek() == stack2.peek());
        stack1.push(a);
        stack2.push(b);
        System.out.println(stack1.peek() == stack2.peek());
        stack1.push(c);
        stack2.push(d);
        System.out.println(stack1.peek() == stack2.peek());
        stack1.push(e);
        stack2.push(f);
        System.out.println(stack1.peek() == stack2.peek());
        System.out.println("==========");
        
        MinStack obj = new MinStack();
        obj.push(512);
        obj.push(-1024);
        obj.push(-1024);
        obj.push(512);
        obj.pop();
        obj.getMin();
        obj.pop();
        obj.getMin();
        obj.pop();
        obj.getMin();
    }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics