快速求棧或佇列中的最大值
1.棧中最大值
棧是按順序壓入,我們維護另外一個棧來記錄棧當前的最大值。如果push值大於輔助棧的頭元素,則輔助棧中壓入要push的值,否則重複壓入輔助棧的頭元素。
簡單來說:push的時候兩個棧都push,max棧push的時候要比較要push的元素和棧頂元素的大小,誰大push誰。程式碼參考如下。(這種情況下我們維護的max棧的大小和data棧的大小相同)
#include<iostream> #include<stack> using namespace std; template<typename T> class Cstack { private: stack<T>s; stack<T>maxs; public: void pushV(T& value); void popV(); T& getPeek(); T& getMax(); }; template<typename T> void Cstack::pushV(T &value) { if(s.empty()) { s.push(value); maxs.push(value); } else { s.push(value); int tmp=maxs.top(); if(tmp>value)maxs.push(tmp); else maxs.push(value); } } template<typename T> void Cstack::popV() { if(s.empty()) throw("empty stack!"); s.pop(); maxs.pop(); } template<typename T> T & Cstack::getPeek() { if(s.empty()) throw("empty stack!"); return s.top(); } template<typename T> T& Cstack::getMax() { if(s.empty()) throw("empty stack!"); return maxs.top(); }
當然有優化的地方,就是空間上maxs棧不用儲存連續相同的最大值。也有看到用陣列來類比棧的,另外一個數組來記錄最大值的位置,基本上思想是一樣的。
2.佇列的最大值
如果說棧增長的方向是單方向的,在push新元素時,只用更新新push元素所對應的最大值即可,因為之前壓入不受後壓入的元素的影響。影響只有:新壓入元素受已壓入元素的最大值的影響。已壓入元素對應的最大值不受影響。
佇列不同,新壓入元素的對應的最大值不受已壓入元素的影響(因為他們會先pop),也就是他們僅和當前壓入元素相關。複雜的是已壓入的元素會受新壓入 元素的影響。那麼解決方案有兩種。
第一種,用multiset記錄佇列中的元素,push時insert集合,pop時刪除相關值,求最大值時利用集合自動排序即可獲得。
第二種:先來看下兩個棧實現一個佇列。這時我先說這兩個棧一個是資料棧,一個是輸出棧。push、pop的操作文中寫了,那麼如何求最大值呢?
資料棧和輸出棧分別維護一個最大值棧,如棧中快速求取最大值的方法(1)。思路如下:
兩個佇列實現一個棧的程式碼有了,只是在push的時候注意data1和max1捆綁,data2和max2捆綁。pop時也一樣。求最大值時要在max1和max2中求最大的。