1.實現一個棧, 要求 : Push, Pop, Min 操作的 時間複雜度 均爲 O( 1 ).
思路: 首先, 我們先否定一種思路: 用一個變量保存每次入棧後 棧中最小值, 這種思路的問題在於, 第一次返回最小值是正確的, 可是這個最小值被 Pop 掉後, 次小值如何獲得呢.接着 我想到了 ,用數組保存 每個元素, 每次元素入棧時進行比較 , 按降序 排序, 後來發現這種思路 既麻煩又沒有必要我們用一個 輔助棧 minS 來保存 最小值, 一共有兩個棧 dataS 棧 和 minS 棧, minS 棧用來實現 Min( ) Fun 功能
我們給 一組數據 即可明白 假如入棧序列:棧底 -> 1226 521 626 8 2 6 7 1 9 <- 棧頂 從 1226 ---> 9 元素分別入棧 dataS 下面我們分析 dataS 的元素入棧情況:
我們進行分析: 首先 我們從開始 進行分析 開始入棧 1226 爲最小元素 入 minS 棧,接着入棧 521 成爲最小元素 ,入 minS 棧這時我們重點進行分析 626入棧 dataS後 此時最小元素 爲 什麼? 依然爲521 假設現在 dataS 棧中只有 三個元素 1126 521 626 在元素 521 出棧前, Min函數 返回值爲 521 也就是說 ,只要 521 後面入棧的元素 比 521 大, 根本不用擔心 Min 函數返回值的事, 我們根本不用管 minS 棧的入棧問題, 直到有一個 入棧元素 比之前 的最小值 小 ,我們纔將這個元素入 minS 棧,之後的思路, 和前面類似。 到了這裏, 我們就明白, 根本不用 用 數組加排序來 實現 Min我們要做的是 用 另外一個棧 來實現我們的 Min( ) 功能.代碼:
#include <iostream> #include <windows.h> #include <stack> using namespace std; template <typename T> class MyStack { public: void Push( const T& data ) { dataS.push( data ); if ( 1 == dataS.size( ) ) //第一次入棧 minS.push( data ); else if ( data <= minS.top( ) ) minS.push( data ); } void Pop( ) { if ( minS.top( ) == dataS.top( ) ) //注意到我們這裏的刪除 條件 ,所以 , 入棧 minS 時的判斷條件是 <= 而不是 < { dataS.pop( ); minS.pop( ); } else dataS.pop( ); } T& Min( ) { return minS.top( ); } private: stack<T> dataS; stack<T> minS; }; void TestMyStack( ) { MyStack<int> s; s.Push( 2 ); cout << s.Min( ) << endl; s.Push( 3 ); s.Push( 5 ); cout << s.Min( ) << endl; s.Push( 1 ); cout << s.Min( ) << endl; s.Push( 6 ); s.Push( 3 ); s.Push( 1 ); cout << s.Min( ) << endl; //2351631 s.Pop( ); cout << s.Min( ) << endl; s.Pop(); s.Pop(); s.Pop(); //235 cout << s.Min( ) << endl; } int main( ) { TestMyStack(); system( "pause" ); return 0; }