LeetCode打卡day5

96 阅读2分钟

“Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。”

一、题目描述: 请定义一个队列并实现函数 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]

限制:

1 <= push_back,pop_front,max_value的总操作数 <= 10000

1 <= value <= 10^5

二、思路分析:

使用一个辅助队列maxq,我们希望当要获取最大值时,返回maxq的首位,当我们排出首位时当首位不是最大值时没影响,但当首位是最大值值时我们希望原maxq的第二位就是原对象的第二大的值。那么如何实现呢?

如果我们只把大于maxq的值插入,那么面对 9 1 1时删除首位不能得到新的最大值1,而面对9 1 1 10时却能符合要求,这是因为10在1后面,1对maxq影响已经没有了,故10加入时因排出所有小于10的数

因为队列queue是先进先出的,当出现第二大时可能与最大值相隔很多的比他小的值,而这些小值先于第二大值排出且对最大值顺序没影响,故我们把maxq中小于第大二的值全部排出再加入;而最大值先排出,这样第二大值顺位推进。

故辅助队列maxq中按降序排列,插入新值时从maxq队列尾部依次取出比当前元素小的元素,直到遇到一个比当前元素大的元素。这样前面的无关的小值不会影响

  1. max_value,为空返回-1,否则返回首位
  2. push_back 为空两个队列都加入,否则maxq队列尾部依次取出比当前元素小的元素再加入
  3. pop_front 为空返回-1,否则判断删除的是否为最大值,是删除首位,否不做操作

三、AC代码

var MaxQueue = function() {
    this.maxq=[];
    this.queue=[];
};

/**
 * @return {number}
 */
MaxQueue.prototype.max_value = function() {
    let maxq=this.maxq;
    if(maxq.length){
        return maxq[0]
    }else return -1
};

/** 
 * @param {number} value
 * @return {void}
 */
MaxQueue.prototype.push_back = function(value) {
    let [maxq,queue]=[this.maxq,this.queue];
    while(maxq.length&&maxq[maxq.length-1]<value)maxq.pop()
    maxq.push(value);
    queue.push(value);
    
};

/**
 * @return {number}
 */
MaxQueue.prototype.pop_front = function() {
    let [maxq,queue]=[this.maxq,this.queue];
    if(queue.length){
        let value=queue.shift();
        if(value===maxq[0])maxq.shift()
        return value;
    }else return -1;
};

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

四、总结

本题和请定义一个最大栈大同小异,都是借助了对应的辅助数据结构。对最大栈来说,因为栈先进后出,其辅助栈只需加入比原先大的值即可;对最大队列来说,因为队列先进先出,辅助栈加入时要把比新值小的数全部排出。