面试题59 - II. 队列的最大值


面试题59 - II. 队列的最大值

请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。

若队列为空,pop_front 和 max_value 需要返回 -1

示例 1:

输入:
[“MaxQueue”,”push_back”,”push_back”,”max_value”,”pop_front”,”max_value”]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]
示例 2:

输入:
[“MaxQueue”,”pop_front”,”max_value”]
[[],[],[]]
输出: [null,-1,-1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

我们知道对于一个普通队列,push_back 和 pop_front 的时间复杂度都是 \mathcal{O}(1)O(1),因此我们直接使用队列的相关操作就可以实现这两个函数。

对于 max_value 函数,我们通常会这样思考,即每次入队操作时都更新最大值:

59.gif
https://pic.leetcode-cn.com/839e8856c964e437c7bd17faf24d1b0524b35e819296af3d81866c15b77fa478-59.gif

但是当出队时,这个方法会造成信息丢失,即当最大值出队后,我们无法知道队列里的下一个最大值。

fig2.gif
https://pic.leetcode-cn.com/571cfb44a14bd3c77ee6563b23e6efaa48419cd12cd3c5a43190a36d4d129592-fig2.gif

解题思路:

为了解决上述问题,我们只需记住当前最大值出队后,队列里的下一个最大值即可。

具体方法是使用一个双端队列 dequedeque,在每次入队时,如果 dequedeque 队尾元素小于即将入队的元素 valuevalue,则将小于 valuevalue 的元素全部出队后,再将 valuevalue 入队;否则直接入队。

fig3.gif
https://pic.leetcode-cn.com/9d038fc9bca6db656f81853d49caccae358a5630589df304fc24d8999777df98-fig3.gif
这时,辅助队列 dequedeque 队首元素就是队列的最大值。

代码: c++

class MaxQueue {
public:
    queue<int> q;
    deque<int> d;

    MaxQueue() {
        while(!q.empty()){
            q.pop();
        }
        while(!d.empty()){
            d.pop_front();
        }
    }

    int max_value() {
        if(d.empty()){
            return -1;
        }
        return d.front();
    }

    void push_back(int value) {
        q.push(value);
        while(!d.empty() && d.back()<value){
            d.pop_back();
        }
        d.push_back(value);
    }

    int pop_front() {
        if(q.empty()){
            return -1;
        }
        if(q.front()==d.front()){
            d.pop_front();
        }
        int ret = q.front();
        q.pop();
        return ret;
    }
};

/**
 * Your MaxQueue object will be instantiated and called as such:
 * MaxQueue* obj = new MaxQueue();
 * int param_1 = obj->max_value();
 * obj->push_back(value);
 * int param_3 = obj->pop_front();
 */

文章作者: anlen123
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 anlen123 !
 上一篇
归并排序 归并排序
归并排序视频教程 //归并排序 /*********************/ void merge(int arr[],int L,int M,int R){ int left_size = M-L; int right_
2020-05-07 anlen123
下一篇 
面试题62. 圆圈中最后剩下的数字 面试题62. 圆圈中最后剩下的数字
面试题62. 圆圈中最后剩下的数字约瑟夫环问题0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。 例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第
2020-05-07 anlen123
  目录