🚩传送门:力扣题目
题目
请定义一个队列并实现函数 得到队列里的最大值,要求函数
、
和
的均摊时间复杂度都是
。
若队列为空, 和
需要返回
。
示例 1:
输入: [“MaxQueue”,”push_back”,”push_back”,”max_value”,”pop_front”,”max_value”][[],[1],[2],[],[],[]] 输出: [null,null,null,2,1,2]
解题思路:单调双端队列
如下图所示,考虑构建一个 递减列表 来保存队列 所有递减的元素 ,递减链表随着入队和出队操作实时更新,这样队列最大元素就始终对应递减列表的首元素,实现了获取最大值 时间复杂度。
复杂度分析
时间复杂度:,函数
、
和
的均摊时间复杂度都是
。
空间复杂度:,当元素个数为
时,最差情况下 deque 中保存
个元素;
我的代码
class MaxQueue {
LinkedList<Integer> resQueue = null;
LinkedList<Integer> maxQueue = null;
public MaxQueue() {
resQueue = new LinkedList<>();
maxQueue = new LinkedList<>();
}
public int max_value() {
if (!maxQueue.isEmpty()) return maxQueue.peekFirst();
return -1;
}
public void push_back(int value) {
// resQueue添加当前值
resQueue.addLast(value);
if (maxQueue.isEmpty()) {
// 最大队列空,直接添加
maxQueue.addLast(value);
} else if (value > maxQueue.peekFirst()) {
// value大于最大值,直接清空,添加当前元素
maxQueue.clear();
maxQueue.addLast(value);
} else if (value < maxQueue.peekLast()) {
// 小于最小值
maxQueue.addLast(value);
} else {
// 移除中间值
while (!maxQueue.isEmpty() && maxQueue.peekLast() < value) {
maxQueue.pollLast();
}
// maxQueue添加当前值
maxQueue.addLast(value);
}
}
public int pop_front() {
if (!resQueue.isEmpty()) {
int pop = resQueue.pollFirst();
if (maxQueue.peekFirst() == pop)
maxQueue.pollFirst();
return pop;
}
return -1;
}
public static void main(String[] args) {
MaxQueue mq = new MaxQueue();
}
}