题目描述
解题思路
思路1(暴力解法)
使用队列的特性尾部插入,头部删除实现 push_back 和 pop_front, 至于寻找最大值,则遍历队列元素,找到最大值就返回,否则返回 -1。
时间复杂度:max_value 为O(n), 其余为 O(1) 空间复杂度: O(n)
代码略
思路2(维护一个单调的双端队列)
我们从上面分析得知,实际上最耗时的是找到最大值,那么我们可以针对这个寻找过程做一些优化,增加一个队列,这个队列里面存放最大值。
- push_back 元素时, 普通的队列(队列1)直接在队尾添加元素,而单调队列则需要判断一下,如果队列的头部元素比当前元素都要小,将整个队列的元素出队,再将当前元素添加到队尾
- max_value 时,如果队列2不为空,则它的队首元素为最大值,否则,没有最大值,返回 -1.
代码
JS
var MaxQueue = function() {
this.queue1 = [];
this.queue2 = [];
}
MaxQueue.prototype.push_back = function(value){
// 单调队列里的最大值比当前值小,则清空整个队列。
while(this.queue2.length && this.queue2[this.queue2.length - 1] < value){
this.queue2.pop();
}
this.queue1.push(value);
this.queue2.push(value);
}
MaxQueue.prototype.pop_front = function(){
// 队列为空,返回 -1
if(!this.queue1.length) return -1;
// 元素存在,返回队头删除的元素
const val = this.queue1.shift();
if(this.queue2.length && this.queue2[0] === val){
this.queue2.shift();
}
return val;
}
MaxQueue.prototype.max_value = function(){
return this.queue2.length ? this.queue2[0] : -1
}
总结
关键思路在于如何优化的取得最大值的时间复杂度(max_value), 利用单调队列,维护最大值即可,同时记得删除队首元素的时候,判断一下该元素是否正好也在单调队列中即可。
时间复杂度: O(1)
空间复杂度: O(n)