题目内容
设计一个支持 push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
- push(x) —— 将元素 x 推入栈中。
- pop() —— 删除栈顶的元素。
- top() —— 获取栈顶元素。
- getMin() —— 检索栈中的最小元素。
示例:
输入: ["MinStack","push","push","push","getMin","pop","top","getMin"] [[],[-2],[0],[-3],[],[],[],[]] 输出: [null,null,null,null,-3,null,0,-2] 解释: MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> 返回 -3. minStack.pop(); minStack.top(); --> 返回 0. minStack.getMin(); --> 返回 -2.
提示:
pop
、top
和getMin
操作总是在 非空栈 上调用。
解题思路
在解决这道题时,采用的思路是使用一个辅助栈用于存储当前栈中最小的值。在添加第一个元素时存储最小值的栈一定为空,而此时添加的第一个元素也一定是当前最小的元素,因此就将当前元素压入最小栈中。接下来其他元素再进行入栈时与当前存储最小值的栈中的栈顶元素进行比较,如果要入栈的元素值小于栈顶元素就将该元素同时压入存储最小值的辅助栈中。同理,在将一个元素进行出栈操作时也要与存储最小值的元素进行一次值的比较,如果此时要出栈的元素值等于当前辅助栈的栈顶元素时就将辅助栈中的栈顶元素一起出栈。
解题代码
class MinStack { Stack<Integer> stack; Stack<Integer> minStack; public MinStack() { // 在调用构造方法时创建两个栈 stack = new Stack<>(); // 创建辅助栈用来存储最小值 minStack = new Stack<>(); } public void push(int val) { // 在入栈时要注意如果当前元素为最小元素则额外将其添加到辅助栈中 // 先将要入栈的元素与当前辅助栈中的元素进行比较 if (minStack.isEmpty() || minStack.peek() >= val) { minStack.push(val); } stack.push(val); } public void pop() { // 在取出元素时先与辅助栈中的元素进行比较,如果值一致则一并出栈 // 要使用equals进行比较 if (stack.pop().equals(minStack.peek())) { minStack.pop(); } } public int top() { // 返回栈的栈顶指针即可 return stack.peek(); } public int getMin() { // 直接返回最小栈的栈顶指针即可 return minStack.peek(); } } /** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.push(val); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */
题目收获
在这道题中,思路上和代码逻辑上没有阻碍,但是在进行元素值的比较时出现了一次问题导致解答出错情况的出现。问题在于Java中Integer
类型的数据与Integer
类型的数据在比较时应该使用equals()
方法进行比较,而我一开始使用的是==
符号进行比较而导致出错。在这里进行记录和总结,将==
与equals()
方法的比较进行记录强化理解和记忆。
总结记录
在Java中Integer
类型是int
类型数据的包装类,因为在JDK1.5之后具有了一个新的特性自动拆装箱,所以在Integer
类型的数据与int类型数据进行比较时对于Integer类型的数据都会经历一次自动拆箱的过程,因此本质上还是相当于两个int类型的数据在进行比较,而两个Integer类型的数据进行比较时又有着以下两种情况
- 当两个不是通过
new Integer()
这样的方式而是通过Integer num = 100;
这种方式得到的Integer
类型数据时,Integer
类型的数据值在-128~127这个区间内的话,因为此时Integer
类型的数据作为一个常量时对于这个区间的数会进行缓存,所以这种情况下的比较相当于在比较同一个地址,对于超出这个区间的数字就是相当于通过new Integer()
来得到一个新的对象。 - 无论什么样的情况,只要是与通过
new Integer()
这样的方式得到的Integer
类型的数据进行比较时都是相当于在比较两个不同的对象,因此是不会相同的
因此在包装类型间的相等判断应该用equals,而不是’==’,在此进行记录,引以为戒!