定義棧的資料結構在Theta(1)時間複雜度內實現min,pop,push操作

來源:互聯網
上載者:User

思路:
push,pop操作在常量時間複雜度內完成,沒有問題,但是,min操作需要在常量時間複雜度內完成,一開始很容易想到在棧中儲存一個變數min,用來儲存最小值,那麼如果需要min()操作時,只需要查min變數的值即可.這個思路看起來不錯,但是,有一個致命的缺陷,那就是,只儲存一個min變數,那麼當min也需要彈棧的時候,那麼棧中的min也需要用次二小的值更新,但是,此時無法知道第二個小值是哪個,OK,我們也可以試圖儲存第二小的變數secMin,當最小值彈棧的時候,我們就用secMin去更新min變數,但是,此時,secMin也應該需要ThirdMin更新才行,如果ThirdMin也出棧.......這樣下去,我們就需要儲存min,secMin,ThirdMin......等所有小值.因此用儲存常量個變數的辦法顯然無法滿足.我們可以嘗試用一種資料結構來儲存這一系列的最小值.
現在的問題變成了,我們需要一個額外的空間來儲存當前的最小值,即使當前的最小值出棧了,我們依然可以得到最新當前的最小值(無論彈棧,壓棧的過程如何變化),
我們可以嘗試用輔助棧的辦法來解決:
在新定義的棧中儲存一個資料棧和一個輔助棧.輔助棧棧頂儲存的是當前的最小值min.
min()操作時:只需要查輔助棧頂元素
push( _val )操作時:先將_val壓入資料棧,再比較_val和輔助棧頂元素Top,如果_val < Top,則_val壓進輔助棧,使得_val成為當前的最小值
pop()操作時:先將資料棧頂元素彈棧,如果棧頂元素是最小值,彈了輔助棧頂元素(彈出最小值min)
代碼如下:

#include<iostream>#include<stack>using namespace std;struct MinStack{private:stack<int> St;stack<int> Extern;public:void push(int val){St.push(val);if(Extern.empty() || val <= Extern.top())Extern.push(val);}int pop(){if(St.empty()){cout<<"Hello"<<endl;throw "Error";}int Temp=St.top();St.pop();if(Temp == Extern.top())Extern.pop();return Temp;}int min(){if(Extern.empty()){cout<<"Hello2"<<endl;throw "error!";}return Extern.top();}};void main(){MinStack ms;ms.push(2);ms.push(2);ms.push(3);ms.pop();ms.pop();ms.pop();cout<<ms.min();}

還有一種巧妙的解法:

因為需要在theta(1)時間複雜度內完成min()操作,因此,我們可以想方設法把min置於棧頂,但是,push()操作和pop()操作也需要在theta(1)時間複雜度內完成,怎麼辦呢?先考慮pop(),如果棧頂元素正是最小元素.彈棧只需要把min彈出即可,如果棧頂元素element比min大,怎麼辦呢?我們可以在min的下一個元素儲存element-min,彈棧時可以彈出兩個元素,再算二者之和即可.(思考:element有可能比min小嗎?不可能,因為min是最小值)

push( _val )時,因為這裡的棧操作都是兩個元素一起來的,當棧為空白時,_val進棧兩次,棧頂為最小值min.當棧不為空白時,將棧頂元素min替換成(_val-min )和min{_val,min}

具體操作是:min出棧,push(_val-min),push(_val < min?_val : min)

代碼:

#include<iostream>#include<stack>using namespace std;struct MinStack{private:stack<int> St;public:void push(int val){if(St.empty()){St.push(val);St.push(val);}else{int min=St.top();St.pop();St.push(val-min);St.push(val < min ? val : min);}}int pop(){if(St.empty()){cout<<"Pop Error!"<<endl;exit(1);}int min = St.top();  St.pop();int flag = St.top();  St.pop();//彈棧一彈彈兩個if (flag < 0) //flag< 0,說明彈出的是最小值,需要用次二小值更新棧頂{  St.push(min - flag);  return min;  } else {    //彈出的不是最小值,則直接彈出棧,無需更新最小值if (!St.empty()) {  St.push(min);  return flag + min;  }  return min;  }  }int Min(){if(St.empty()){cout<<"Search Min Error!"<<endl;exit(1);}int min=St.top();return min;}};void main(){MinStack ms;ms.pop();ms.pop();ms.pop();cout<<ms.Min();}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.