最長遞增子串行

2021-08-08 12:02:01 字數 1800 閱讀 2154

最長遞增子串行(longest increasing subsequence)是指找到乙個給定序列的最長子序列的長度,使得子串行中的所有元素單調遞增。

例如: 的 lis 是 ,長度為 4。

其實可以把 求最長遞增子串行問題 轉化為 求最長公共子串行的問題。

最長公共子串行的求法見《動態規劃dp》。本方法的時間複雜度是 θ

(nlg

n)+θ

(n2)

=θ(n

2)雖然解法一也是使用動態規劃,但是與解法一不同的是,解法二不進行轉化,而是直接在原問題上採用動態規劃法。

最優子結構:

對於長度為 n 的陣列 a[

n]= ,假設我們想求以ai

結尾的最大遞增子串行長度,設為l[

i],那麼 l

[i]=

⎧⎩⎨m

ax(l

[j])

+1,1

,where 

j<

iand a[

j]i]

otherwise

也就是 

j  的範圍是 0 到 i–

1 。這樣,想求ai

結尾的最大遞增子串行的長度,我們就需要遍歷 

i  之前的所有位置 

j (0到 i-1),找出a[

j]i]

,計算這些

j  中,能產生最大 l[

j]的 

j ,之後就可以求出l[

i]。之後對每乙個a[

n]中的元素都計算以他們各自結尾的最大遞增子串行的長度,這些長度的最大值,就是我們要求的問題——陣列

a 的最大遞增子串行的長度。

重疊子問題:

根據上述推導式採用遞迴實現的話,有些子問題會被計算很多次。

動態規劃法:

綜上所述,lis 問題具有動態規劃需要的兩個性質,可以使用動態規劃求解該問題。設陣列 a = ,則: 

具體的打表方式如下:

打完表以後,最後一行的最大值就是最長遞增子串行的長度。由於每次都進行遍歷,故時間複雜度還是 θ(

n2) 。c

// lis 的動態規劃方式實現
#include using namespace std;

int getlislength(int a, int len)

本解法的具體操作如下:

遍歷結束之後,最長遞增序列長度即為棧的大小

注意c陣列的下標代表的是子串行的長度,c陣列中的值也是按遞增順序排列的。這才可能用二分查詢。

陣列array[i]儲存的是子串行長度為i的序列最後乙個值(該值是該子串行中最大的元素;如果長度為i的序列有多個,那麼array[i]存放這類序列最後元素中的最小乙個)

cop

int getlislength(int num, int length)
ivec[low] = num[i];

} }

return ivec.size();

}特別注意的是:本方法只能用於求最長遞增子串行的長度,輔助陣列中的序列不是最長遞增子串行

最長遞增子串行

這是微軟實習生筆試遇到的,題意 求乙個陣列中最長遞增子串行的長度。要求選擇該題最好演算法的時間複雜度和空間複雜度。答案 時間複雜度o nlgn 空間複雜度o n 這題明顯用動態規劃來解。假設在目標陣列array 的前i個元素中,以array i 元素為最大元素的遞增子串行的長度是lis i 那麼 遞...

最長遞增子串行

最長遞增子串行又叫做最長上公升子串行 子串行,正如lcs一樣,元素不一定要求連續。本節討論實現三種常見方法,主要是練手。題 求乙個一維陣列arr i 中的最長遞增子串行的長度,如在序列1,1,2,3,4,5,6,7中,最長遞增子串行長度為4,可以是1,2,4,6,也可以是 1,2,4,6。方法一 d...

最長遞增子串行

最長遞增子串行 求乙個字串的最長遞增子串行 如 dabdbf最長遞增子串行就是abdf,長度為4 這是一道基本的動態規劃求解的題目,與此類似的還有 最長公共子串行 分析 用一維陣列dp i 來儲存以a i 為末元素的最長遞增子串行的長度,那麼dp i 至少為1 即包含它本身 往前尋找,如果存在a j...