棧和佇列的基礎演算法學習(EPI)

2021-09-06 17:48:41 字數 3220 閱讀 5210

今天學習的時間雖然挺多的,但是總覺效率不高。其實今天沒有按照計畫進行epi題目的瀏覽,白天去看了其他的書籍。準備找工作可能需要的狀態是一定量經典的書,偶爾溫習才可。書是看不完的,知識點也是固定的。所以從把手頭的幾本書在瀏覽完畢之後就要著手複習之前的知識啦。c++的知識,leetcode的題目,作業系統,資料庫,網路的學習筆記~。

1. 實現乙個棧,支援返回當前棧中最大值的操作。要求,返回最大值的操作時間複雜度o(1)。可以使用額外的o(n)的空間複雜度。

題目之前見到過,所以思路一下子就有了,利用額外的棧儲存當前棧中最大值即可。

簡單的思路,在元素入棧的時候,輔助棧同時壓入當前棧的最大值,元素出棧的時候,彈出輔助棧的元素。取得最大值直接從輔助棧棧頂獲取即可。

另外,可以減少一下壓入輔助棧中的元素的數量,只有壓入當前棧的元素大於等於當前輔助棧棧頂元素,才將該至壓入輔助棧棧頂,出棧的時候,只有出棧元素等於輔助棧棧頂元素時,才將輔助棧棧頂彈出。

另外,能在常數項更優化的乙個方法是,輔助棧中壓入乙個數對,數對的意義是當前的最大值,以及當前最大值的數量,push的時候如果相等,則增加數對的第二個值,pop的時候如果相等,減去數對中的第二個值,如果減至0,則pop輔助棧即可。

擴充套件問題,實現乙個佇列,支援返回當前最大值的操作,能否優化至o(1)的時間複雜度。

這個題目還是比較複雜的,需要結合兩個知識來把時間複雜度均攤為o(1),及利用兩個已經實現最大值操作的堆疊來模擬佇列,可以達到均攤o(1)複雜度的返回最大值的佇列。

其實利用deque也能夠達到o(1)的均攤成本,但是時間複雜度分析比較複雜。

均攤的理解是每個元素最多進入d和離開d一次,不會第二次進入和離開d。所以入隊的均攤o(1)。

2.實現逆波蘭表示式的計算並返回計算結果。

利用棧不斷的壓入數字,遇到運算符號,從數字棧中取出兩個數字進行計算,結果繼續壓入數字棧,直到計算完畢,數字棧中儲存的運算結果。

3.迭代方法實現bst的中序遍歷。

利用棧的迭代實現不是很複雜,而且可以完成o(1)空間複雜度的morris中序遍歷。

而且迭代實現二叉樹的遍歷方法中,後序遍歷的實現是難度最大的。morris的後序遍歷實現起來難度也很大。

4.針對隨機鍊錶,即除了next域之外,增加乙個random指標域的鍊錶,迭代的方法進行random-first序的遍歷。

遞迴的方法比較容易實現,這裡讓進行迭代即利用stack來模擬遞迴的方法即可。

template void search_postings_list(const shared_ptr> &l) }}

5.利用棧記錄漢諾塔的移動過程,模擬。

void transfer(const int &n, array,3> &pegs, const int &from, const int & to, const int &use) 

transfer(n,pegs,0,1,2);

}

6.一排樓房所有的窗戶都面朝西,太陽落下的時候如果乙個樓房的西面不存在比該樓房高的樓房,則該樓房可以看到陽光,從東至西計算出所有可以看到陽光的樓房。擴充套件問題:從西至東計算出所有可以看到陽光的樓房。

問題的根本思路是利用棧,從東至西維護乙個遞減的序列。從西至東則需要維護乙個遞增的序列。其中序列的內容及為可看到陽光的樓房。這種利用棧維護單調序列的方法在求最大直方圖面積中應用可以減少時間複雜度至o(n)。

從東至西的遞減序列code 

template vector> examine_buildings_with_sunset(istringstream &sin) 

buildings_with_sunset.emplace_back(idx++,height);

}return buildings_with_sunset;

}

7.設計乙個排序堆疊的演算法僅僅利用push,pop,empty,top操作,並且不顯示的開闢額外空間。如果不顯示的開闢額外空間,就想想利用函式遞迴呼叫的堆疊儲存資訊,這樣就能夠進行排序。比如插入排序的遞迴實現方法。

template void sort(stack&s) 

}template void insert(stack&s,const t &e) else

}

8.將包含..和.的檔案路徑名簡化至最短路徑。思路就是保持乙個棧,當遇到..的時候講棧頂的目錄名彈出,遇到.則忽略。這樣就可以得到最短路徑了。該題目邊界情況較多,屬於細節題。

9.層序遍歷bst的方法。

層序遍歷,即廣度優先搜尋,需要借助佇列來完成功能。

10.利用兩個整數實現乙個佇列的功能。佇列中能夠加入的元素為[0,9]。

首先看到這個題目想到的是將整數看成位陣列,4位可以表示[0,15]之間的數字,所以可以當成陣列。

後來參***看到按照十進位制的位來表示[0,9]計算起來更加方便。剛好十進位制的每位都是[0,9],乙個數字作為陣列,另外乙個數字作為佇列的長度。注意全為0的邊界情況。

擴充套件問題:如果只有乙個整數,可以使用其中一位儲存長度。

11.利用兩個棧實現乙個佇列,使得pop和push的均攤成本o(1)。

乙個棧負責進入佇列,另外乙個棧負責彈出佇列。

12.o(1)返回佇列max值的佇列的應用。

應用場景是現在有乙個陣列,陣列是乙個數對,第乙個元素表示乙個時間戳,第二個元素表示該事件的流量,陣列已經根據時間戳有序的,現在需要計算每個時間戳至時間戳+w這段時間內的最大流量是多少。

如果直接解法則需要遍歷當前時間戳的流量至當前時間戳+w這段時間內所有流量,時間複雜度o(nw)。

如果利用優先佇列的話因為是最小堆實現的,所以可以優化至o(nlogw)的時間複雜度。

如果利用o(1)返回最大值的佇列,則優化至了o(n)的時間複雜度。

演算法學習03 棧和佇列

巨集觀劃分問題 最優解來自於資料狀況或問法 鍊錶問題 筆試與面試要求不同 佇列結構的實現 迴圈佇列 最小棧的pop push getmin 操作的時間複雜度都是o 1 解法 儲存兩個棧,data棧和min棧,data棧儲存壓入的資料,min棧儲存當前棧中最小值 當向data壓入乙個數時,與min棧棧...

前端演算法學習(二) 棧和佇列

特性 後進先出,就好比在乙個只有乙個口的箱子裡放東西,前面先放進去的東西只能後面再拿出來 function stack this.pop function var stack new stack stack.push 1 stack.push 2 stack.push 3 console.log s...

內功 基礎演算法 棧,佇列和堆

下面兩個鏈結是我的leetcode棧和佇列的分類。棧 共40題 佇列 共8題 堆 共31題 1 實現乙個特殊的棧,在實現棧的基本功能的基礎上,再實現返回棧中最小元素的操作。2 怎麼用陣列實現棧和佇列。棧用乙個 index,push 就是 index,pop就是 index 佇列用三個變數,start...