演算法 求最長公升序子串行長度

2021-10-01 17:31:24 字數 2316 閱讀 9331

求乙個陣列中最長公升序子串行的長度。如 [8,4,7,5,1,3,6,2]; 公升序子串行有 [4,7],[4,5,6],[1,3,6],最長公升序子串行的長度為 3。

特別說明:因為題目要求是找到最長公升序子串行的長度,並沒有說找到最長公升序子串行。所以在實現的過程中,只要找到乙個子串行。這個子串行是公升序的,並且保證是最長的。就可以知道其長度

方法:動態規劃 + 二分查詢

該方法的解題關鍵在於,先找到第乙個公升序子串行(把第乙個元素移動到乙個空陣列,將該陣列作為第乙個公升序子串行)。剩餘的元素比這個子串行的最後乙個元素大,則直接移動到該子串行尾部。否則在該序列中找到比其大的最小元素,將其替換掉。替換不會影響最長公升序子串行的長度,其目的是為了讓子串行裡面的元素降到最小,好讓剩餘的元素中數值較大的元素公升序排列

比如陣列 [8,4,7,5,1,3,6,2] 中第乙個公升序序列可以理解為是 [8]。後面的元素 4 比 8 小,就替換掉 8。這個公升序序列就是 [4]。接著是 [4,7],找到 5 時,5 比 7 小。找到 [4,7] 中比 5 大的最大元素,替換掉成為 [4,5]。這是為了讓後面的較大元素能夠公升序排列。如果不替換掉 7,後面的元素 6 就沒法新增到這個序列中來。這裡有點繞,但也是理解這個思路的關鍵所在。

第一步:建立新陣列

定義乙個新陣列 newarr=,先將陣列 arr = [8,4,7,5,1,3,6,2] 中的第乙個元素移動到新陣列,即 newarr=[8],arr = [4,7,5,1,3,6,2] 。

第二步:按照二分查詢對比元素。

迴圈陣列 arr 。通過二分查詢法找到當前元素 arr[0] (因為每操作一次都會刪除掉乙個元素,所以當前元素永遠是第乙個元素)在新陣列 newarr 中的位置。

當前元素與新陣列的中間元素比較,當前元素小。左移,還小,繼續左移。直到當前元素比中間元素 m 大,則替換掉 m+1 索引位置的元素。如果 m 是 0,則直接替換掉第乙個元素。

如:當前元素為 4,在陣列 [3,5,6,7,9] 中找到中間元素 6。當前元素4比6小,左移,將範圍定位到 [3,5,6] 。繼續找到中間元素 5。當前元素還小,繼續左移。將範圍定位到 [3,5]。中間元素為 5。當前元素還小,將範圍定位到 [3]。當前元素4比3大。替換 m+1 索引位置的元素,也就是用 4 替換 5。結果為 [3,4,6,7,9]。

當前元素與新陣列的中間元素比較,當前元素大,右移。還大,繼續右移。直到當前元素比中間元素 m 小,則替換掉 m 索引位置的元素。如果沒有找到比當前元素還大的數。則將當前元素直接新增到新陣列尾部。

如:當前元素為 8,在陣列 [3,5,6,7,9] 中找到中間元素 6 ,當前元素8比6大,右移,將範圍定位到 [6,7,9],繼續找到中間元素 7。當前元素還大小,繼續右移。將範圍定位到 [7,9]。中間元素為 9。當前元素8比9小。替換 m 索引位置的元素,也就是用 9 替換 8。結果為 [3,4,6,7,8]。

var arr =[8

,4,7

,5,1

,3,6

,2];

function

lengthoflis

(arr)

var newarr =

;//先將第乙個元素移動到新陣列中

newarr.

push

(arr.

shift()

);while

(arr.length)

else

newarr[i]

= arr.

shift()

;//找到新陣列元素中比當前元素大的最小元素,用當前元素替換掉該元素。}}

return newarr.length;

}else

} console.

log(

lengthoflis

(arr)

)//3

最後再解釋說明一下替換元素的原因。替換元素的目的其實就是給子串行降級。

比如陣列 [4,7,5,1,3,8,6,2]。一眼看上去最長公升序子串行是[4,5,8]。不做降級處理的話,假設後面又有乙個元素 7。即 [4,7,5,1,3,8,6,2,7] 你的寫法很有可能會過濾掉這個 7。而做了降低處理,上面的方法得到的子串行是 [1,2,6]。最後乙個元素 7 可以如願新增進來。成為[1,2,6,7]。長度為 4。正常的公升序子串行為 [4,5,6,7],長度也為 4。再強調最後一遍,該題求的是最長子序列長度,子串行長度,子串行長度。不是子串行,不是子串行,不是子串行。當然也可以算出子串行,但是時間複雜度可能會大於 o(n*logn)。

求最長公共子串行長度

1.求最長公共子串行 子串行可以不連續 這是一道動態規劃題,設二維陣列dp i j dp i j 表示a串前i個字元 包括第i個 與b串前j個字元 包括第j個 所有的公共子串行的最長長度。例如,a串abbcd,b串abcd,dp 3 3 就表示的a的前三個字元與b的前三個字元的最長公共子串行長度,值...

最長不下降子串行長度

對於序列 1,7,3,5,9,4,8 有它的一些不下降子串行 如 1,7 3,4,8 等等。這些子串行中最長的長度是4,比如子串行 1,3,5,8 input 多組cas 每組cas 兩行 第一行 輸入乙個數 n n 10000 表示有n個數 第二行 n個數,分別代表每個數 output 每個cas...

最長上公升子串行長度 LIS O nlogn 演算法

此前在動態規劃一講 動態規劃 3 最長遞增子串行 曾說過此問題,當前是的雙重迴圈是o n 2 的複雜度。後來在網上看到說lis問題有o nlogn 的演算法,於是拿來小研究了一下。這個演算法其實已經不是dp了,有點像貪心。至於複雜度降低其實是因為這個演算法裡面用到了二分搜尋。本來有n個數要處理是o ...