知識點:隊列;單調函數
請定義一個隊列並實現函數 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(); */