包含min函数的栈

包含min函数的栈 思路及坑

题目要求

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

题目分析

  1. 构造一个栈,栈具有先进后出的特点,且需要一个栈顶指针来指向栈的顶部
  2. 该栈需要能够返回其中最小的函数,且需要时间复杂度为O(1),因此就需要在push 和 pop操作的时候根据操作的值 记录得到一个min值,这样才能保证时间复杂度为O(1).
  3. 考虑到时间复杂度的要求及push和pop都是插入删除操作,因此可使用链表来实现栈的数据结构.

Java的LinkedList是一种常用的数据容器,与ArrayList相比,LinkedList的增删操作效率更高,而查改操作效率较低。
LinkedList 实现了List 接口,能对它进行列表操作。
LinkedList 实现了Deque 接口,能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,能克隆。
LinkedList 实现了java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。

具体的思路

具体就是使用两个LinkedList,A和 B, A用来实现栈,B用来存放该栈的一系列最小值,这个一系列最小值是怎么得来的呢?
具体来说就是,当执行push x操作的时候首先判断x是否小于等于B中的栈顶元素,若小于则push进B,否则就不push,这样当push操作执行完后,B中的栈顶元素返回的就是A的最小的元素min
在执行pop操作的时候,首先判断A中的栈顶元素是否等于B的栈顶,如果是,那么说明当前pop出去的是A的最小值,此时需要把B中的栈顶元素也pop出去。

class MinStack {
        int min = Integer.MAX_VALUE;
        int top = -1;
        int tt = -1;
        LinkedList<Integer> stack;
        LinkedList<Integer> record;
    /** initialize your data structure here. */
    public MinStack() {
        stack = new LinkedList();
        record = new LinkedList();
    }
    
    public void push(int x) {
        top++;
        stack.add(top,x);
        if(x<=min){
            tt++;
            record.add(tt,x);
            min = x;
        }
    }
    
    public void pop() {
    
        if(stack.getLast() == record.getLast()){
            record.remove(tt);
            tt--;
        }
        
        
        stack.remove(top);

        top--;

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

    }
    
    public int min() { 
        return record.getLast();

    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.min();
 */

其中LinkedList 方法的getLast() 方法定义为:
public E getLast(),返回最后一个元素,其返回的是E,在上面的代码里也就是Integer。

//输入case
["MinStack","push","push","push","min","pop","top","min"]
[[],[-2],[0],[-3],[],[],[],[]]

//我的输出
[null,null,null,null,-3,null,0,-2]
//完美符合 预期

但是在提交的时候发现通过不了,具体的case为:

//输入
["MinStack","push","push","push","push","pop","min","pop","min","pop","min"]
[[],[512],[-1024],[-1024],[512],[],[],[],[],[],[]]

//我的输出
[null,null,null,null,null,null,-1024,null,-1024,null,-1024]
//预期的输出应该为:
[null,null,null,null,null,null,-1024,null,-1024,null,512]

//看输出 应该是在最后一个pop的时候出现了问题

经过一番分析发现,和上面说的getLast方法有关系,在java中,存在着自动装箱拆箱的操作,具体可参看这个文章:
自动装箱
简单来说在值 为i < 128 && i >= -128 的时候直接返回的是已创建好的对象,而当超出这个范围的时候会创建不同的对象,因此在输入为-1024的时候 stack.getLast() == record.getLast() 是不会为true的
知道了原因之后,改起来也就很容易了,只需要拿到E的值,用这个值去判断就可以了。在JDK1.5 之后,可直接使用 int i = stack.getLast(); 自动拆箱

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值