剑指Offer-面试题59-II:队列的最大值 双端队列法

这里是题目描述:剑指Offer-面试题59-II:队列的最大值

本题和与它同属于一个大题的剑指Offer-面试题59-I:滑动窗口的最大值都可以用双端队列来存储当前的最大值以及接下来可能成为最大值的元素,来优化时间开销

借助双端队列的解法

本题要求max_valuepush_backpop_front 的均摊时间复杂度都是O(1)。而其中的主要难点就在于让任何状态下的max_value时间复杂度为O(1)。我们要考虑的是,如何用O(1) 的时间复杂度返回队列中的最大值,同时保证如果最大值出队列,最大值状态发生变化后,依然可以用 O(1) 的时间复杂度找到新的最大值

我们除了需要使用一个单向队列存储进队、出队的元素外,还需建立一个双端队列,借助它存储当前状态下的最大值和可能成为后续状态最大值的值,其中当前最大值位于队头,保证 O(1) 的时间开销可以找到最大值。当有新元素进队列,将它与双端队列队尾元素比较,若队尾元素较小,则证明它不再机会成为某一状态下的最大元素,因为它无论如何会比当前新进队列的元素先出队列,则让队尾元素出队,新元素继续和队尾比较,直到它小于等于队尾元素或双端队列为空,则让它从队尾进入双端队列;当有元素出队列,当出队列元素和双端队列队头值相等时,双端队列队头出队列,新的双端队列队头就是新状态下的最大值

在这里插入图片描述
题解代码:

class MaxQueue {
    Queue<Integer> queue; //存储队列元素
    Deque<Integer> maxValueDeque; //存储当前队列中的最大值和可能的后续最大值
    public MaxQueue() {
        queue=new LinkedList<>();
        maxValueDeque=new LinkedList<>();
    }

    public int max_value() {
        if(queue.size()==0)
        {
            return -1;
        }
        return maxValueDeque.getFirst();
    }

    public void push_back(int value) {
        queue.offer(value);
        enDeque(maxValueDeque,value);
    }

    public int pop_front() {
        if(queue.size()==0)
        {
            return -1;
        }
        int popValue=queue.remove();
        if(popValue==maxValueDeque.getFirst())
        {
            maxValueDeque.removeFirst();
        }
        return popValue;
    }

    public void enDeque(Deque<Integer> deque,int value)
    {
        while(deque.size()>0)
        {
            if(deque.getLast()<value)
            {
                deque.removeLast();
            }
            else
            {
                break;
            }
        }
        deque.offerLast(value);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值