剑指 Offer 59II - 队列的最大值
Posted xintangchn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 59II - 队列的最大值相关的知识,希望对你有一定的参考价值。
力扣链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/
题目描述
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
思路:单调队列+辅助队列
使用单调队列存储最大值,即新数a入队前,先弹出队列中所有比a小的数,因为只要a存在,这些数都不可能成为队列中的最大值。
使用辅助队列记录所有数字,当弹出的数与最大值相同时,两个队列同时弹出。
算法:
两个数组成员:单调队列monotonicQueue, 辅助队列queue
push_back(num):
num进入辅助队列queue
弹出单调队列中所有比num小的数
num进入单调队列
pop_front():
if(!queue.length) return -1;
弹出辅助队列首部popped
如果popped与单调队列首部一样,弹出单调队列首部
返回popped
max_value():
if(!queue.length) return -1;
return monotonicQueue[0];
代码:
var MaxQueue = function() { this.monotonicQueue = []; this.nums = []; }; /** * @return {number} */ MaxQueue.prototype.max_value = function() { if(!this.nums.length) return -1; return this.monotonicQueue[0]; }; /** * @param {number} value * @return {void} */ MaxQueue.prototype.push_back = function(value) { let {monotonicQueue, nums} = this; nums.push(value); while(value > monotonicQueue[monotonicQueue.length-1]){ monotonicQueue.pop(); } monotonicQueue.push(value); }; /** * @return {number} */ MaxQueue.prototype.pop_front = function() { let {monotonicQueue, nums} = this; if(!nums.length) return -1; let popped = nums.shift(); if(popped === monotonicQueue[0]){ monotonicQueue.shift(); } return popped; }; /** * 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() */
时间复杂度:O(1)
空间复杂度:O(N)
对于插入操作均摊时间复杂度O(1)的解释:建立一个长度为N的队列,每个元素最多入队一次出队一次,因此均摊到每个元素上的出队次数为1,因此插入的均摊时间复杂度为O(1)
以上是关于剑指 Offer 59II - 队列的最大值的主要内容,如果未能解决你的问题,请参考以下文章
剑指offer59 - II 至 剑指offer 64 题解