資料結構 優化單調棧求最長上公升子串行

2022-06-29 12:15:09 字數 1240 閱讀 6756

先說說什麼是單調棧,此部分內容**

有兩種:

模擬單調棧的資料push和pop

模擬實現乙個遞增單調棧:

現在有一組數10,3,7,4,12。從左到右依次入棧,則如果棧為空或入棧元素值小於棧頂元素值,則入棧;否則,如果入棧則會破壞棧的單調性,則需要把比入棧元素小的元素全部出棧。單調遞減的棧反之。

至於出現相等的元素根據題目要求進行取捨。

好,切入正題。

對於前乙個舉例的單調棧,如果新加入的元素大於棧頂元素,我們是從棧頂for到棧底,直到找到第乙個小於它的元素,那麼要增加乙個元素時間複雜度最壞是o(n)。所以要用上upper_bound或lower_bound函式去查詢第乙個小於它的元素(用陣列模擬棧),然後直接用要插入的元素替換即可,當然,不用彈出之前的棧頂元素,它們還有作用。這樣每次增加乙個元素時間複雜度最壞為o(logn)。

這樣優化就完成了,當然,為了解決問題。我們要研究的是單調棧優化後所具有的一些新的性質。接下來先給出方法,然後用數學歸納法(遞推)去證明:

先梳理一遍:對於求乙個序列的(棧內不允許重複元素),我們可以維護乙個優化單調棧,將原序列的元素從頭開始通過某種方法不斷壓入,使得棧內每個元素的下標為以該元素為結尾的連續上身子序列的最長長度(這個是新的性質,也是要證明的內容)。把原序列最後乙個元素壓入時,棧頂元素的下標就是就是最長長度。

步驟:

證明:

假設,壓入第i-1個元素後,棧內元素的下標表示以該元素為結尾的最長上公升序列長度,且棧內元素保持公升序(為了方便理解,下面都預設從棧底到棧頂)。

那麼,壓入第i個元素時:

最後一點我解釋得很馬虎,但也不難想,有個大前提就是每個元素都是順序加入的,聯絡起來分類討論一段時間就可以想通了。

好了,由於壓入的第乙個元素的棧滿足假設,那麼之後所有都滿足。

以下是奇醜無比的**

len=1;

sta[len]=h[1];//h為原序列,sta陣列模擬棧

for(int i=2;i<=cnt;++i)

}printf("\n%d",len);

return 0;

}}

同樣的思路,譬如最長連續下降子串行啊,最長不下降子串行啊,最長連續不上公升子串行啊,都同理可寫。

順帶一提,不上公升和不下降那個用的是upper_bound。

如果有錯誤歡迎批評。

求最長上公升子串行

q 有乙個長為n的數列a0,a1,an 1。求出這個序列中最長的上公升子串行的長度。上公升子串行指的是對於任意的i大致思路是這樣的,初始設定乙個最大長度maxlength為0,從數列的第一項開始遍歷,只要當前項大於前一項則加入,否則繼續遍歷,直至此次遍歷結束。然後與maxlength做對比,如果大於...

求最長上公升子串行

由n個不相同的整數組成的數列,記為 a 1 a 2 a n 且a i a j i j 例如,3,18,7,14,10,12,23,41,16,24.若存在i1 i2 3 e且有a i1 2 e 則稱其為長度為e的不下降子串行。如上例中3,18,23,24就是乙個長度為4的不下降子串行,同時也有3,7...

求最長上公升子串行

通常求最長上公升子串行的做法是兩層for迴圈,這裡從別人那裡學會了另一種sao操作 includeusing namespace std int n int a 500005 int up 500005 儲存上公升的長度 int down 500005 下降的長度 int u 500005 最大化上...