定义一个队列并实现函数 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)和之前做过的实现栈的最小值有异曲同工之妙:LeetCode-Stack-155-E:最小值
(2)本题使用的是双端队列,思想是求滑动窗口最大值的问题,ArrayDeque
具体内容如下:
ArrayDeque是JDK容器中的一个双端队列实现,内部使用数组进行元素存储,不允许存储null值,可以高效的进行元素查找和尾部插入取出,是用作队列、双端队列、栈的绝佳选择,性能比LinkedList还要好。
1.添加元素
addFirst(E e)在数组前面添加元素
addLast(E e)在数组后面添加元素
offerFirst(E e) 在数组前面添加元素,并返回是否添加成功
offerLast(E e) 在数组后天添加元素,并返回是否添加成功
2.删除元素
removeFirst()删除第一个元素,并返回删除元素的值,如果元素为null,将抛出异常
pollFirst()删除第一个元素,并返回删除元素的值,如果元素为null,将返回null
removeLast()删除最后一个元素,并返回删除元素的值,如果为null,将抛出异常
pollLast()删除最后一个元素,并返回删除元素的值,如果为null,将返回null
removeFirstOccurrence(Object o) 删除第一次出现的指定元素
removeLastOccurrence(Object o) 删除最后一次出现的指定元素
3.获取元素
getFirst() 获取第一个元素,如果没有将抛出异常
getLast() 获取最后一个元素,如果没有将抛出异常
4.队列操作
add(E e) 在队列尾部添加一个元素
offer(E e) 在队列尾部添加一个元素,并返回是否成功
remove() 删除队列中第一个元素,并返回该元素的值,如果元素为null,将抛出异常(其实底层调用的是removeFirst())
poll() 删除队列中第一个元素,并返回该元素的值,如果元素为null,将返回null(其实调用的是pollFirst())
element() 获取第一个元素,如果没有将抛出异常
peek() 获取第一个元素,如果返回null
5.栈操作
push(E e) 栈顶添加一个元素
pop(E e) 移除栈顶元素,如果栈顶没有元素将抛出异常
6.其他
size() 获取队列中元素个数
isEmpty() 判断队列是否为空
iterator() 迭代器,从前向后迭代
descendingIterator() 迭代器,从后向前迭代
contain(Object o) 判断队列中是否存在该元素
toArray() 转成数组
clear() 清空队列
clone() 克隆(复制)一个新的队列
解法1
class MaxQueue {
//List<Integer> queue = new LinkedList<>();
//List<Integer> maxQueue = new LinkedList<>)();
// 双端队列
private Deque<Integer> queue;
private Deque<Integer> maxQueue;
public MaxQueue() {
queue = new ArrayDeque<>();
maxQueue = new ArrayDeque<>();
}
public int max_value() {
if(queue.isEmpty()){
return -1;
}
return maxQueue.peek();
}
public void push_back(int value) {
queue.offer(value);
//maxQueue
while(!maxQueue.isEmpty() && value > maxQueue.peekLast()){
maxQueue.pollLast();
}
maxQueue.offer(value);
}
public int pop_front() {
if(queue.isEmpty()){
return -1;
}
//maxQueue
int tmp = queue.pop();
if(maxQueue.peek() == tmp){
maxQueue.pop();
}
return tmp;
}
}
/**
* 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();
*/
解法1-2
(1)出栈方法这样写就会有bug,必须将peek()和判断条件拆开写。
public int pop_front() {
if(queue.isEmpty()){
return -1;
}
if(queue.peek() == maxQueue.peek()){
maxQueue.poll();
}
return queue.poll();
}