题干
请定义一个队列并实现函数 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 <= push_back,pop_front,max_value的总操作数 <= 10000
1 <= value <= 10^5
想法
双数组
每个数组双指针
一个维护队列本身的先进先出 用于push 和pop
一个维护大小 大的在前
Java代码
package daily;
public class MaxQueue {
int QueueHead = 0;
int QueueTail = 0;
int[] Queue;
int MaxQueueHead = 0;
int MaxQueueTail = 0;
int[] MaxQueue;
public MaxQueue() {
Queue = new int[10000];
MaxQueue = new int[10000];
}
public int max_value() {
if (MaxQueueHead == MaxQueueTail) {
return -1;
}
return MaxQueue[MaxQueueHead];
}
public void push_back(int value) {
Queue[QueueTail++] = value;
while (MaxQueueHead != MaxQueueTail && MaxQueue[MaxQueueTail-1] < value) {
//找到value合适的位置
MaxQueueTail--;
}
MaxQueue[MaxQueueTail++] = value;
}
public int pop_front() {
if (QueueHead==QueueTail){
return -1;
}
int res = Queue[QueueHead];
if(res == MaxQueue[MaxQueueHead]){
MaxQueueHead++;
}
QueueHead++;
return res;
}
}
显然用树就更简单
更快的办法
class MaxQueue {
private Node max;
private Node root;
private Node tail;
class Node{
int val;
Node next=null;
public Node(int val){this.val=val;}
}
public MaxQueue() {
this.root=new Node(-1);
root.next=null;
this.max=root;
this.tail=root;
}
public int max_value() {
if(root==tail)return -1;
return max.val;
}
public void push_back(int value) {
Node tmp=new Node(value);
tail.next=tmp;
tail=tmp;
if(max==root||max.val<=value)max=tmp;
}
public int pop_front() {
if(tail==root)return -1;
root=root.next;//root并不代表实际节点
if(root==max){//最大值要出去了
Node head=root.next;//head-tail才代表实际的队列
max=head;
while(head!=null){
max=max.val<=head.val?head:max;
head=head.next;
}
}
max=(max==null)?root:max;
return root.val;
}
}
/**
* Your MaxQueue object will be instantiated and called as such:
* MaxQueue obj = new MaxQueue();
* int param_1 = obj.max_value();
* obj.push_back(value);
* int param_3 = obj.pop_front();
*/