题目:队列的最大值
定义一个队列并实现函数max得到队列里的最大值。要求max,pushBack,popFront的时间复杂度都是o(1)。
思路:
将上一题的滑动窗口看成一个队列即可。入队时间复杂度o(1),出队时间复杂度o(1),调整记录下标的双端队列的时间复杂度最差为o(n),获取最值得时间复杂度为o(1)。
基于以上思路,java参考代码如下:
package chapter6;
import java.util.ArrayDeque;
public class P292_QueueWithMax {
public class myData{
int val;
int index;
public myData(int val,int index){
this.val=val;
this.index=index;
}
}
private ArrayDeque<myData> maxdeque=new ArrayDeque<>();
private ArrayDeque<myData> datadeque=new ArrayDeque<>();
private int cur=0;
public void push(int number){
while (!maxdeque.isEmpty()&&number>=maxdeque.peekLast().val){
maxdeque.pollLast();
}
maxdeque.addLast(new myData(number,cur));
datadeque.addLast(new myData(number,cur));
cur++;
}
public int pop(){
if(maxdeque.isEmpty()){
throw new RuntimeException("Queue is empty !");
}
if(maxdeque.peekFirst().index==datadeque.peekFirst().index){//two Datas are the same number.
maxdeque.pollFirst();
}
return datadeque.pollFirst().val;
}
public int getMax(){
if(maxdeque.isEmpty()){
throw new RuntimeException("Queue is empty !");
}
return maxdeque.peekFirst().val;
}
public static void main(String[] args) {
P292_QueueWithMax maxDeque=new P292_QueueWithMax();
maxDeque.push(2);
maxDeque.push(6);
maxDeque.push(2);
maxDeque.push(5);
System.out.println(maxDeque.getMax());//6
maxDeque.pop();
maxDeque.pop();
System.out.println(maxDeque.getMax());//5
}
}
java参考代码二如下:
import java.util.ArrayDeque;
import java.util.Deque;
public class QueueWithMax {
public static class QueueWithMax<T extends Comparable> {
private Deque<InternalData<T>> queueData;
private Deque<InternalData<T>> queueMax;
private int currentIndex;
public QueueWithMax() {
this.queueData = new ArrayDeque<>();
this.queueMax = new ArrayDeque<>();
this.currentIndex = 0;
}
public T max(){
if(queueMax.isEmpty())
return null;
return queueMax.getFirst().value;
}
public void pushBack(T value){
while (!queueMax.isEmpty()&&value.compareTo(queueMax.getLast().value)>=0)
queueMax.removeLast();
InternalData<T> addData = new InternalData<>(value,currentIndex);
queueMax.addLast(addData);
queueData.addLast(addData);
currentIndex++;
}
public T popFront(){
if(queueData.isEmpty())
return null;
InternalData<T> delData = queueData.removeFirst();
if(delData.index==queueMax.getFirst().index)
queueMax.removeFirst();
return delData.value;
}
private static class InternalData<M extends Comparable> {//InternalData为一个结构体数据,包含值和索引两个元素
public M value;
public int index;
public InternalData(M value,int index){
this.value = value;
this.index = index;
}
}
}
public static void main(String[] args) {
QueueWithMax<Integer> queue = new QueueWithMax<>();
queue.pushBack(3);
System.out.println(queue.max());
queue.pushBack(5);
System.out.println(queue.max());
queue.pushBack(1);
System.out.println(queue.max());
System.out.println("开始出队后,调用max");
System.out.println(queue.max());
queue.popFront();
System.out.println(queue.max());
queue.popFront();
System.out.println(queue.max());
queue.popFront();
System.out.println(queue.max());
}
}
测试用例:
a.往队列末尾插入不同大小的数字并求最大值;从队列头部删除数字并求最大值。