劍指Offer_#59-II_佇列的最大值
阿新 • • 發佈:2020-07-27
劍指Offer_#59-II_佇列的最大值
Contents
題目
請定義一個佇列並實現函式 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
思路分析
這一題跟劍指Offer_#59-I_滑動視窗的最大值,劍指Offer_#30_包含min函式的棧都有共通之處,可以說是這兩題的一個結合。
#30
題中,我們使用一個輔助棧來儲存每種狀態下的最小值。與30題不同的是,這裡是實現佇列結構,所以不能用棧作為輔助變數。可以借鑑#59
題中的雙端佇列結構來實現功能,即雙端佇列作為輔助變數,儲存每種狀態下的最大值。在操作原始資料佇列的同時,同步操作輔助雙端佇列。使得無論什麼時候,雙端佇列的第一個元素就是原始資料佇列的最大值。
詳見如下圖解,來自 評論區題解。
解答
class MaxQueue {
Deque<Integer> maxDeque;
Queue<Integer> queue;
public MaxQueue() {
queue = new LinkedList<>();
maxDeque = new LinkedList<>();
}
public int max_value() {
if(!maxDeque.isEmpty() && !queue.isEmpty())
return maxDeque.peekFirst();
else
return -1;
}
public void push_back(int value) {
queue.offer(value);
while(!maxDeque.isEmpty() && value > maxDeque.peekLast())
maxDeque.removeLast();
maxDeque.addLast(value);
}
public int pop_front() {
//ERROR:Integer作為包裝類物件,不能直接用==比較,必須用equals()方法比較,見《Core Java》P193
if(!maxDeque.isEmpty() && maxDeque.peekFirst().equals(queue.peek()))
maxDeque.removeFirst();
if(!queue.isEmpty())
return queue.poll();
else
return -1;
}
}
複雜度分析
時間複雜度:max_value、push_back 和 pop_front 的複雜度都是O(1)
空間複雜度:O(n),需要藉助一個輔助的雙端佇列