最長遞增子串行(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...