一,問題描述
給定乙個序列,求解它的最長 遞增 子串行 的長度。比如: arr = 的最長遞增子串行長度為4。即為:1,4,5,9
二,演算法分析
有兩種方式來求解,一種是轉化為lcs問題。即,首先對陣列排序,將排序後的結果儲存在輔助陣列中。排序時間複雜度o(nlogn),排序後的陣列與原陣列組成了lcs(n,n)問題。解決lcs問題的時間複雜度為o(n^2),故整個演算法的時間複雜度為o(n^2),空間複雜度為o(n)
另一種方式是直接用dp求解,演算法如下:時間複雜度為o(n^2)
①最優子問題
設lis[i] 表示索引為 [0...i] 上的陣列上的 最長遞增子串行。初始時,lis[i]=1,注意,在dp中,初始值是很重要的,它是整個演算法執行正確的關鍵。而初始值 則可以 通過 畫乙個小的示例來 確定。
當 arr[i] > arr[j],lis[i] = max+1 ;其中,j 的取值範圍為:0,1...i-1
當 arr[i] < arr[j],lis[i] = max ;其中,j 的取值範圍為:0,1...i-1
②重疊子結構
從上面可以看出,計算 lis[i]時,需要計算 lis[j],其中 j < i,這說明有重疊子問題。借用網路中一張圖如下:
lis(4)而初始值 則可以 通過 畫乙個小的示例來 確定。/ | \
lis(3) lis(2) lis(1)
/ \ /
lis(2) lis(1) lis(1)
/
lis(1)
求解兩個字串的最長公共子串行
動態規劃(3)-最長遞增子串行
三,**實現
錯誤版本1:
1第13行if語句會導致bug,arr[i]要大於 j belongs to 0,1,...i-1 中所有的 arr[j]中的最大值,並且 lis[i] 是該最大值arr[j] 所對應的 lis[j] +1,而不是某個其他的arr[j] 對應的 lis[j]+1private
static
int lis(int arr, int length)
18else
22 }
23 }
24return lis[length - 1];
25 }
正確完整版本:
public
class lis
private
static
int lis(int arr, int length)
if(arr[i] > arr[j] && lis[j] + 1 > lis[i])
lis[i] = lis[j] + 1;}}
int max = lis[0];
for(int i = 1; i < length; i++)
if(max < lis[i])
max = lis[i];
return max;
}public
static
void main(string args) ;
int result = lis(arr);
system.out.println(result);}
動態規劃求解最長遞增子串行的長度
一,問題描述 給定乙個序列,求解它的最長 遞增 子串行 的長度。比如 arr 的最長遞增子串行長度為4。即為 1,4,5,9 二,演算法分析 有兩種方式來求解,一種是轉化為lcs問題。即,首先對陣列排序,將排序後的結果儲存在輔助陣列中。排序時間複雜度o nlogn 排序後的陣列與原陣列組成了lcs ...
使用動態規劃求解最長遞增子串行(LIS)
給定乙個數列,數列中的數是未排序 可重複的,求其最長遞增子串行 lis 的長度。如數列1 7 3 5 9 4 8其lis為 1 3 5 9 或1 3 5 8 則輸出其長度4。先將數列存入陣列array中 然後把array n 的lis長度存入陣列result n 中,如在數列1 7 3 5 9 4 ...
動態規劃 最長遞增子串行
給出序列 1 2 3 4 2 5 3 4 a 1 1,a 2 2,a 7 3,a 8 4 求其最長的遞增子串行,以上最長遞增子串行為 1 2 3 4 5 問題細分 初始化條件f 1 1,序列只有1個長度即為1 f 2 a 2 與下標小於2的比較,即a 1 比較,a 2 a 1 因此更新f 2 f 1...