问题
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
思想
-
用LinkedList结构模拟队列,remove(0)表示出队,add()表示入队
-
每一次push和pop对队列的最大值都会产生影响。
1)push操作:如果加入的数值value比当前队列的max_value大,那么需要更新max_value;反之,新加入的数值不会对max_value有影响
2)pop操作:如果删除的不是max_value,那么就没有影响,直接删除即可;反之,需要得知在该数值之后队列的max_value,那么就需要有一个数据结构来记录该信息。 -
用Stack记录max_value信息(其它数据结构也可)
1)push操作:value小于等于栈顶元素时,表明新加入的数据不会影响之前队列的max_value,但是它可能会成为之后队列的max_value,所以直接加到栈中(这里等于栈顶元素的也加入栈中是害怕后序pop操作中删掉了max_value信息而导致错误发生); value大于栈顶元素,表明该数据的加入会影响之前队列的max_value,作出如下修改:
while(max.peek()<value) {
max.pop();
if(max.isEmpty()) {
break;
}
}
max.push(value);
2) pop操作:stack.get(0)始终记录了当前队列的max_value,当删除的值等于max_value时剔除。
代码
class MaxQueue {
LinkedList<Integer> queue;
Stack<Integer> max;
public MaxQueue() {
queue = new LinkedList();
max = new Stack();
}
public int max_value() {
return max.peek();
}
public void push_back(int value) {
queue.add(value);
if(max.isEmpty()) {
max.push(value);
} else {
while(max.peek()<value) {
max.pop();
if(max.isEmpty()) {
break;
}
}
max.push(value);
}
}
public int pop_front() {
int front = queue.remove(0);
if(max.get(0)==front) {
max.pop();
}
return front;
}
}