題目描述:請定義乙個佇列並實現函式 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、單調佇列 + 雙端佇列:
我們知道,對於乙個普通佇列來說,在隊尾插入元素和刪除隊首元素的時間複雜度為o(1),因此這道題的難點在於如何在平均時間複雜度為o(1)的情況下得到最大元素。可以參考劍指 offer 59 - i. 滑動視窗的最大值的思路,維護乙個隊內元素非嚴格遞減的雙端佇列,這樣隊首元素就是佇列中的最大元素。
因此,可以使用乙個普通佇列queue
,這樣就可以在o(1)
時間複雜度內刪除元素,然後使用乙個單調雙端佇列deque
,在每次插入元素時保證deque
的元素非嚴格遞減,具體的做法是:迴圈比較隊尾元素和新元素,如果隊尾元素比新元素小,將隊尾元素移出,最後再插入新元素。這樣就能保證deque
的隊首元素就是佇列中的最大元素,可以滿足平均時間複雜度為o(1)
的要求。
注1:由於刪除元素時可能會刪除的元素是最大元素的情況,因此在刪除元素時需要判斷一下,如果是最大元素則需要更新雙端佇列(即刪除雙端佇列的隊首元素)。
注2:這道題的思路和劍指 offer 59 - i. 滑動視窗的最大值和劍指 offer 30. 包含min函式的棧的思路很相似,可以一起分析總結。
時間複雜度:刪除元素和求最大元素操作的時間複雜度明顯為o(1),而插入元素雖然看起來有迴圈,但是由於每個數字只會入隊和出隊一次,因此對於 n 個數字的插入過程,所有時間均攤到每個插入操作上,平均時間複雜度為o(1)。
實現**:
class
maxqueue
//取最大元素
public
intmax_value()
//push操作
public
void
push_back
(int value)
//pop操作
public
intpop_front()
}
劍指Offer 59 II 佇列的最大值
請定義乙個佇列並實現函式 max value 得到佇列裡的最大值,要求函式max value push back 和 pop front 的均攤時間複雜度都是o 1 若隊列為空,pop front 和 max value 需要返回 1 額外維護乙個雙端佇列,用來儲存當前佇列可能的最大值,且是有序的,...
劍指 Offer 59 II 佇列的最大值
請定義乙個佇列並實現函式 max value 得到佇列裡的最大值,要求函式max value push back 和 pop front 的均攤時間複雜度都是o 1 若隊列為空,pop front 和 max value 需要返回 1 示例 1 輸入 maxqueue push back push ...
劍指 Offer 59 II 佇列的最大值
請定義乙個佇列並實現函式 max value 得到佇列裡的最大值,要求函式max value push back 和 pop front 的均攤時間複雜度都是o 1 若隊列為空,pop front 和 max value 需要返回 1 示例 1 輸入 maxqueue push back push ...