标签:link 复杂 链接 代码 每日 fir 数字 要求 题目
时间: 2019-07-05
题目链接:Leetcode
tag: 队列 双端队列
难易程度:中等
题目描述:
请定义一个队列并实现函数 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. 1 <= push_back,pop_front,max_value的总操作数 <= 10000
2. 1 <= value <= 10^5
本题难点
时间复杂度有要求为O(N)
具体思路
使用两个队列:一个队列正常入队出队;再用一个双端队列来辅助作为单调队列,维护队头最大值。这样max_value()查询,单调队列队首的值就是查询的最大值。
class MaxQueue {
Queue<Integer> queue;
Deque<Integer> deque;
public MaxQueue() {
queue = new LinkedList<>();
deque = new LinkedList<>();
}
public int max_value() {
//单调队列队首就是最大值
return queue.isEmpty() ? -1 : deque.peekFirst();
}
public void push_back(int value) {
queue.add(value);
//维护单调队列的单调性:把小的都出队了 队列剩余的都是比当前元素大的,所以是单调递增,队首就是最大值
//如果之前入队的队尾比后入队的当前元素还要小,就让队尾出队
while(!deque.isEmpty() && deque.peekLast() < value){
deque.pollLast();
}
deque.add(value);
}
public int pop_front() {
//当普通队列的队首元素 等于 单调队列队首 就让单调队列队首出队
if(!deque.isEmpty() && deque.peekFirst().equals(queue.peek())){
deque.pollFirst();
}
return queue.isEmpty() ? -1 : queue.poll();
}
}
复杂度分析:
每日一题 - 剑指 Offer 59 - II. 队列的最大值
标签:link 复杂 链接 代码 每日 fir 数字 要求 题目
原文地址:https://www.cnblogs.com/ID-Wangqiang/p/13273078.html