[路飞]_解题技巧之双队列

91 阅读1分钟

剑指 Offer 59 - II. 队列的最大值

这道题是最值问题,又是队列的最值问题,实际上很容易想到去维护一个最大堆,但是维护最大堆的时间复杂度并不符合该题的要求, 这道题有比较符合该时间复杂度的解法,就是使用双队列,一个队列只维护最大值,另一个队列按加入的顺序来构成队列

var MaxQueue = function() {
    // 最大值的队列
    this.maxQueue = []
    // 按添加顺序维护的队列
    this.queue = []
};

/**
 * @return {number}
 */
MaxQueue.prototype.max_value = function() {
    // 返回最大值
    return this.maxQueue[0] || -1
};

/** 
 * @param {number} value
 * @return {void}
 */
MaxQueue.prototype.push_back = function(value) {
    this.queue.push(value); // 按顺序添加到普通队列中
    // 判断最大值的队列的末尾元素是否比当前value小,如果小,那就进行弹出,直到所有小于value的元素都弹出为止
    while(this.maxQueue.length &&
    this.maxQueue[this.maxQueue.length - 1] < value ){
        this.maxQueue.pop()
    }
    this.maxQueue.push(value)
};

/**
 * @return {number}
 */
MaxQueue.prototype.pop_front = function() {
    if(!this.queue.length){
        return -1;
    }
    let val = this.queue.shift()
    // 如果正常队列弹出的值与最大值相等,那记录最大值的队列也要弹出
    if(val === this.maxQueue[0]){
        this.maxQueue.shift()
    }
    return val
};

/**
 * 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()
 */