【劍指offer】59 - II. 隊列的最大值

劍指 Offer 59 - II. 隊列的最大值

知識點:隊列;單調函數

題目描述

請定義一個隊列並實現函數 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();
 */
相關文章
相關標籤/搜索