您的位置:首页 > 理论基础 > 数据结构算法

【数据结构与算法】最长公共子串 最长公共子序列

2017-03-07 05:19 309 查看
1.最长公共子串:找出s和t的公共子字符串的最大长度。

使用dp,定义子问题dp[i][j]:公共子串结束在位置i,j的长度。如果s[i] != t[j],那么很显然是0,否则dp[i][j] = dp[i - 1][j - 1] + 1。

代码:

public int longestCommonSubString(String s, String t){
int[][] dp = new int[s.length()][t.length()];
int max = 0;
for(int i = 0; i < s.length(); i++){
for(int j = 0; j < t.length(); j++){
if(s.charAt(i) == t.charAt(j))
dp[i][j] = 1 + ((i - 1 < 0 || j - 1 < 0)?0:dp[i - 1][j - 1]);
else
dp[i][j] = 0;
max = Math.max(dp[i][j], max);
}
}
return max;
}


2.最长公共子序列:找出s和t的公共子序列的最大长度,子序列不需要连续。

使用dp,定义子问题dp[i][j]:s[0-i]和t[0-j]的最长公共子序列长度。那么首先可以利用之前的结论,即dp[i][j] = max(dp[i - 1][j] + dp[i][j - 1])无论什么情况,dp[i][j]都等于这个。这是由于子序列的性质,大的范围成立,小的范围当然也成立。然后看如果s[i]=t[j],那么还可以用dp[i - 1][j - 1] +1 来尝试,dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1)。

代码:

public int longestCommonSubSequence(String s, String t){
int[][] dp = new int[s.length() + 1][t.length() + 1];
for(int i = 1; i <= s.length(); i++){
for(int j = 1; j <= t.length(); j++){
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
if(s.charAt(i - 1) == t.charAt(j - 1))
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);
}
}
return dp[s.length()][t.length()];
}


从这里可以看出串和序列的区别。串要求连续,只要有一处不同就不能被后面的利用。但是序列不同,后面的总可以利用前面的结果。所以可以说串是遍历所有的可能,而序列是遍历所有的范围。取最大时,串必须取所有可能的最大,而序列只需要看最大的范围即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐