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中确实有此机制——常量池,以后有时间可以查查编译后的字节码验证下。
从这题得到的教训就是:[color=red]以后遇到Integer的比较要转为intValue()[/color],这样最保险。

[补充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。[url]https://leetcode.com/discuss/15679/share-my-java-solution-with-only-one-stack[/url]
思路2:比较清晰的方案,空间换时间。栈中保存元素是自定义的一个类,该类有两个属性,一个是当前元素,一个是当前最小值,不考虑栈本身所占空间,其空间复杂度比两个栈还高。[url]https://leetcode.com/discuss/15679/share-my-java-solution-with-only-one-stack[/url]
思路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();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值