知识点:队列;单调函数
请定义一个队列并实现函数 max_value 获得队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。code
若队列为空,pop_front 和 max_value 须要返回 -1队列
输入: ["MaxQueue","push_back","push_back","max_value","pop_front","max_value"] [[],[1],[2],[],[],[]] 输出: [null,null,null,2,1,2] 输入: ["MaxQueue","pop_front","max_value"] [[],[],[]] 输出: [null,-1,-1]
当一个元素进入队列时,它前面全部比它小的元素就不会再对答案产生影响了rem
好比数字序列 1 1 1 1 2,那么在第一个数字 2 被插入后,数字 2 前面的全部数字 1 将不会对结果产生影响。由于若是数字 1 在队列中,那么数字 2 必然也在队列中(先进先出),使得数字 1 对结果没有影响。ast
因此当从队列尾部插入元素时,能够把没有影响的,也就是全部比要插入元素小的数字都取出来,使得队列中只保留对结果有影响的数字,也就是要求队列单调递减;class
在元素入队时,判断当前元素和队尾的关系,把全部小于当前值的队里元素都移除;object
因此能够在添加和删除的时候采用普通的队列;
在取出最大值的时候采用双端队列;双端队列维持递减,因此每次取出队首元素便可;List
class MaxQueue { Queue<Integer> queue; Deque<Integer> deque; public MaxQueue() { queue = new LinkedList<>(); deque = new LinkedList<>(); } public int max_value() { if(deque.isEmpty()) return -1; return deque.peekFirst(); } public void push_back(int value) { queue.offer(value); while(!deque.isEmpty() && value > deque.peekLast()){ deque.removeLast(); //维持一个单调递减队列; } deque.offerLast(value); } public int pop_front() { if(queue.isEmpty()) return -1; int ans = queue.poll(); if(ans == deque.peekFirst()){ deque.removeFirst(); } return ans; } } /** * 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(); */