题目描述
- 请定义一个队列实现函数max得到队列里的最大值。要求函数max、push_back和pop_front的时间复杂度都为O(1)。
解题思路
- 用双端队列maximums保存最大值。用currentIndex记录push进队列数字的index。
- push_back的时候,如果push的值number大于maximums的队尾元素,则删除队尾元素,直到maximums中没有比number小的值。
- pop_front的时候,如果pop的数据对应的index和maximums队首元素对应的index值一样,则移除maximums的队首元素。
- maximums的队首元素即为当前队列的最大值。
代码
static class QueueWithMax {
static class InternalData{
int number;
int index;
InternalData(int n, int i) {
this.number = n;
this.index = i;
}
}
Deque<InternalData> data = new LinkedList<>(); // 存储队列数据
Deque<InternalData> maximums = new LinkedList<>(); // 存储最大值的队列
int currentIndex = -1; //记录push进队列的index
public void push_back(int number){
currentIndex ++;
while (!maximums.isEmpty() && number > maximums.peekLast().number) {
// number大于maximums的队尾元素,则删除队尾元素,直到maximums中没有比number小的值。
maximums.pollLast();
}
InternalData idata = new InternalData(number, currentIndex);
maximums.offer(idata);
data.offer(idata);
}
public int pop_front(){
if (maximums.isEmpty()) {
throw new RuntimeException("queue is empty!");
}
InternalData idata = data.poll();
if (idata.index == maximums.peek().index) {
// 如果pop的数据对应的index和maximums队首元素对应的index值一样,则移除maximums的队首元素。
maximums.poll();
}
return idata.number;
}
public int max(){
if (maximums.isEmpty()) {
throw new RuntimeException("queue is empty!");
}
return maximums.peek().number;
}
}
网友评论