最長公共子串(動態(tài)規(guī)劃)
掃描二維碼
隨時隨地手機(jī)看文章
來源:https://www.cnblogs.com/fanguangdexiaoyuer/p/11281179.html
1 描述
有兩個字符串(可能包含空格),請找出其中最長的公共連續(xù)子串,輸出其長度。(長度在1000以內(nèi))
例如:
輸入:abcde bcd
輸出:3
2 解析
1、把兩個字符串分別以行和列組成一個二維矩陣。
2、比較二維矩陣中每個點(diǎn)對應(yīng)行列字符中否相等,相等的話值設(shè)置為1,否則設(shè)置為0。
3、通過查找出值為1的最長對角線就能找到最長公共子串。
比如:str=acbcbcef,str2=abcbced,則str和str2的最長公共子串為bcbce,最長公共子串長度為5。
針對于上面的兩個字符串我們可以得到的二維矩陣如下:
從上圖可以看到,str1和str2共有5個公共子串,但最長的公共子串長度為5。
為了進(jìn)一步優(yōu)化算法的效率,我們可以再計(jì)算某個二維矩陣的值的時候順便計(jì)算出來當(dāng)前最長的公共子串的長度,即某個二維矩陣元素的值由record[i][j]=1演變?yōu)閞ecord[i][j]=1 +record[i-1][j-1],這樣就避免了后續(xù)查找對角線長度的操作了。修改后的二維矩陣如下:
遞推公式為:
當(dāng)A[i] != B[j],dp[i][j] = 0
當(dāng)A[i] == B[j],
若i = 0 || j == 0,dp[i][j] = 1
否則 dp[i][j] = dp[i - 1][j - 1] + 1
3 代碼
暴力法
public int getLCS(String s, String s2)
{
if (s == null || t == null)
{
return 0;
}
int l1 = s.length();
int l2 = t.length();
int res = 0;
for (int i = 0; i < l1; i++)
{
for (int j = 0; j < l2; j++)
{
int m = i;
int k = j;
int len = 0;
while (m < l1 && k < l2 && s.charAt(m) == t.charAt(k)) {
len++;
m++;
k++;
}
res = Math.max(res, len);
}
}
return res;
}
動態(tài)規(guī)劃
public int getLCS(String s, String t)
{
if (s == null || t == null)
{
return 0;
}
int result = 0;
int sLength = s.length();
int tLength = t.length();
int[][] dp = new int[sLength][tLength];
for (int i = 0; i < sLength; i++) {
for (int k = 0; k < tLength; k++) {
if (s.charAt(i) == t.charAt(k)) {
if (i == 0 || k == 0) {
dp[i][k] = 1;
} else {
dp[i][k] = dp[i - 1][k - 1] + 1;
}
result = Math.max(dp[i][k], result);
} else {
dp[i][k] = 0;
}
}
}
return result;
}
簡化一下遞推公式:
當(dāng)A[i] != B[j],dp[i][j] = 0
否則 dp[i][j] = dp[i - 1][j - 1] + 1
全部都?xì)w結(jié)為一個公式即可,二維數(shù)組默認(rèn)值為0
public int getLCS(String s, String t)
{
if (s == null || t == null)
{
return 0;
}
int result = 0;
int sLength = s.length();
int tLength = t.length();
int[][] dp = new int[sLength + 1][tLength + 1];
for (int i = 1; i <= sLength; i++) {
for (int k = 1; k <= tLength; k++) {
if (s.charAt(i - 1) == t.charAt(k - 1)) {
dp[i][k] = dp[i - 1][k - 1] + 1;
result = Math.max(dp[i][k], result);
}
}
}
return result;
}
點(diǎn)【在看】是最大的支持
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!