题目描述:
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
思路分析:
这里需要定义一个队列,“MaxQueue”方法可以返回这个队列中最大的元素。
思路一:定义一个中间变量,来存储存入队列中的最大值。
问题:如果当前弹出的值为最大值,那么该中间变量为空,就无法获得剩余队列中的最大值。
思路二:定义一个队列来储存,按照大小顺序来存储。因为我们知道队列中队尾的元素,因此这个用来存储最大值的队列,只需要存储到最小为队尾的元素的大小就行。就比如排队,我们要找的是队伍中最高的那一个,根据队列后进后出的原则,我们只需要把高于队尾的人的身高记录下来就行。因为不管队列中的值怎么弹出,队列中的最大值不可能小于队尾的元素。
class MaxQueue {
LinkedList<Integer> link1;
LinkedList<Integer> link2;
public MaxQueue() {
link1 = new LinkedList<>();
//link2双端队列:获取最大值
link2 = new LinkedList<>();
}
public int max_value() {
return link2.isEmpty() ? -1 : link2.peek();
}
public void push_back(int value) {
link1.offer(value);
//元素一定会被存入队列一
while (!link2.isEmpty() && value > link2.peekLast()) {
//如果队列二中有小于该元素的数
//从队尾开始删除
link2.pollLast();
}
//将该值存入队列二的队尾
//此时队列二按大小顺序排列(最小值为输入的值)
link2.offer(value);
}
public int pop_front() {
if (!link2.isEmpty() && link1.peek().equals(link2.peek())) {
//如果要移除的列头=队列二的列头,则将队列二的列头也移除
link2.pop();
}
return link1.isEmpty() ? -1 : link1.poll();
}
}