23-11-28

文章介绍了如何使用ArrayList和Deque实现一个具有前后中操作的高效FrontMiddleBackQueue类,通过维护两个双端队列来简化对队列中部元素的处理,确保在添加和删除时的平衡性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1670. 设计前中后队列

使用ArrayList(看到别人说的人才库做法,笑死了hhhhh)

class FrontMiddleBackQueue {
    List<Integer> list=new ArrayList<>();

    public FrontMiddleBackQueue() {

    }
    
    public void pushFront(int val) {
        list.add(0,val);
    }
    
    public void pushMiddle(int val) {
        list.add(list.size()/2,val);
    }
    
    public void pushBack(int val) {
        list.add(val);
    }
    
    public int popFront() {
        return list.isEmpty()?-1:list.remove(0);
    }
    
    public int popMiddle() {
        return list.isEmpty()?-1:list.remove((list.size()-1)/2);
    }
    
    public int popBack() {
        return list.isEmpty()?-1:list.remove(list.size()-1);
    }
}

/**
 * Your FrontMiddleBackQueue object will be instantiated and called as such:
 * FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
 * obj.pushFront(val);
 * obj.pushMiddle(val);
 * obj.pushBack(val);
 * int param_4 = obj.popFront();
 * int param_5 = obj.popMiddle();
 * int param_6 = obj.popBack();
 */

 如果只用在首位删除和增加,只用一个双端列表

如果是首、中、尾,需要两个双端列表

我采用了left.size()=right.size()||left.size()=right.size()+1。但其实在做的过程中,发现允许right比left大1会更简单,因为pushmiddle和popmiddle的时候,若不为正中,都取的中间两个靠前的数,所以允许后端的队列长更合理。

比如:如果此时是left=right+1,pushmiddle,需要先把left尾巴给right在添加在left后面,而如果是right=left+1,可直接添加到left尾巴上。其余关于middle的操作都是更简单的,

class FrontMiddleBackQueue {
    private final Deque<Integer> left=new ArrayDeque<>();
    private final Deque<Integer> right=new ArrayDeque<>();
    
    //banlance,保证left=right||left=right+1
    private void balance(){
        if(left.size()>right.size()+1){
            right.addFirst(left.pollLast());
        }else if(left.size()<right.size()){
            left.addLast(right.pollFirst());
        }
    }

    public FrontMiddleBackQueue() {

    }

    //前插,left首加入,banlance    
    public void pushFront(int val) {
        left.addFirst(val);
        balance();
    }
    
    //中插,若left=right,left尾插;若left=right+1,left的尾移到right的头,然后left尾插
    public void pushMiddle(int val) {
        if(left.size()==right.size()){
            left.addLast(val);
        }else{
            right.addFirst(left.pollLast());
            left.addLast(val);
        }
    }
    
    //尾插,right尾插,然后balance
    public void pushBack(int val) {
        right.addLast(val);
        balance();
    }
    
    //取前,判断是否为空。若不为空,取left头,然后balance
    public int popFront() {
        if(left.isEmpty()){
            return -1;
        }
        int val=left.pollFirst();
        balance();
        return val;
    }
    
    //取中,先判断是否为空。若不为空,left=right,取left尾巴,然后balance,若left=right+1,取left尾巴
    public int popMiddle() {
        if(left.isEmpty()){
            return -1;
        }
        int val=0;
        if(left.size()==right.size()){
            val=left.pollLast();
            balance();
        }else{
            val=left.pollLast();
        }
        return val;
    }

    //取尾,判断是否为空,若不为空,判断right是否为空,若为空,返回left尾巴,若不为空返回right尾巴    
    public int popBack() {
        if(left.isEmpty()){
            return -1;
        }
        int val=right.isEmpty()?left.pollLast():right.pollLast();
        balance();
        return val;
    }
}

/**
 * Your FrontMiddleBackQueue object will be instantiated and called as such:
 * FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
 * obj.pushFront(val);
 * obj.pushMiddle(val);
 * obj.pushBack(val);
 * int param_4 = obj.popFront();
 * int param_5 = obj.popMiddle();
 * int param_6 = obj.popBack();
 */

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值