面試中除了排序問題,還會經常出現字串的子串行問題,這裡講解使用動態規劃解決三個常見的子串行問題:
1、最長公共子串行問題(lcs,longest-common-subsequence problem)
2、最長連續公共子串行問題
3、最長遞增子串行(lis,longest-increment-subsequence)
給定兩個序列x=
,x2,
...,
xmx 1,
x2,.
..,x
m>和y=
,y2,
...,
yny 1,
y2,.
..,y
n>,求x和y的最長公共子串行。(子串行可以是不連續的,比如就是的子串行)
例如:輸入兩個字串 bdcaba 和 abcbdab,字串 bcba 和 bdab 都是是它們的最長公共子串行,則輸出它們的長度 4,並列印任意乙個子串行。
時間複雜度o(m*n),空間複雜度o(m*n)。
在使用動態規劃之前先規定一下符號,給定乙個序列x=
,x2,
...,
xmx 1,
x2,.
..,x
m>,定義xi
x
i為x的字首,即xi
x i=
,x2,
...,
xix 1,
x2,.
..,x
i>。
在求x=
,x2,
...,
xmx 1,
x2,.
..,x
m>和y=
,y2,
...,
yny 1,
y2,.
..,y
n>的乙個lcs時,我們需要求解乙個或者兩個子問題。如果xm
=yn xm=
yn,那麼我們應該求解xm
−1=y
n−1 xm−
1=yn
−1的乙個lcs。如果xm
≠yn xm≠
yn,我們必須求解兩個子問題:求xm
−1x m−
1和y y
的乙個lcs與
x' role="presentation" style="position: relative;">xx和
yn−1
y n−
1的乙個lcs。兩個lcs中較長的乙個,即為x和y的乙個lcs,經過推理可知,這些子情況覆蓋了所有可能出現的情況。
所以遞推公式為:
具體到實際的例子中:
// 列印c陣列
for(int i=0;i<=x.length;i++)
system.out.println();
}return c;
}// 輸出lcs序列
public
static
void
print(int arr, char x, char y, int i, int j) else
if(arr[i-1][j] >= arr[i][j-1]) else
}public
static
void
main(string args) ;
char y =;
int c = lengthoflcs(x,y);
print(c, x, y, x.length, y.length);
}}給定兩個序列x=
,x2,
...,
xmx 1,
x2,.
..,x
m>和y=
,y2,
...,
yny 1,
y2,.
..,y
n>,求x和y的最長公共公共子串行。(連續子串行必須連續的)
例如:輸入兩個字串 acbac和 acaccbabb,則最大連續子串為 「cba」, 則返回長度 3。
時間複雜度o(m*n),空間複雜度o(m*n)。
這個 lcs 跟前面說的最長公共子串行的 lcs 不一樣,不過也算是 lcs 的乙個變體,在 lcs 中,子串行是不必要求連續的,而子串則是 「連續」 的。
我們還是像之前一樣 「從後向前」 考慮是否能分解這個問題,類似最長公共子串行的分析,這裡,我們使用c[i,j] 表示 以 xi 和 yj 結尾的最長公共子串的長度,因為要求子串連續,所以對於 xi 與 yj 來講,它們要麼與之前的公共子串構成新的公共子串;要麼就是不構成公共子串。故狀態轉移方程:
}給定乙個序列x=
,x2,
...,
xmx 1,
x2,.
..,x
m>,求x的最長遞增子串行。(子串行可以是不連續的,比如 的lis是5,6,7,8
時間複雜度o(n^2),空間複雜度o(n)。
dp[i]怎麼計算?
遍歷所有j < i的元素,檢查是否dp[j]+1>dp[i] && arr[j] < arry[i] 若是,則可以更新dp[i]
以 的lis是5,6,7,8舉例:
如何選取dp[5]的值呢?就是在所有8之前的小於8的值(即j < i && arr[j] < arry[i])中,選擇dp[j]最大的值,
dp[i] = dp[j] + 1
dp[5] = dp[2] + 1 = 3 + 1 = 4
int maxlength = 1, bestend = 0;
dp[0] = 1;
prev[0] = -1;
for (int i = 1; i < n; i++)
if (dp[i] > maxlength)
最長公共連續子串和最長連續公共子串行
用二維陣列c i j 記錄串x1 x2 x i x1x2 xi與y 1y 2 y j y1y2 yj 的lcs長度,則可得到狀態轉移方程c i,j 0c i 1 j 1 1max c i,j 1 c i 1,j i 0 orj 0i,j 0a ndxi y j i,j 0a ndxi y j pub...
最長公共子串行 最長公共子串
1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...
最長公共子串行 最長公共子串
1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...