题目:
给定两个字符串str1和str2,输出两个字符串的最长公共子串
题目保证str1和str2的最长公共子串存在且唯一。
示例1
输入:
"1AB2345CD","12345EF"返回值:
"2345"备注:
1≤∣str1∣,∣str2∣≤5 0001 \leq |str_1|, |str_2| \leq 5\,0001≤∣str1∣,∣str2∣≤5000
思路:动态规划问题。
先确定状态,f(i, j)表示str1中前i个字符和str2中前j个字符中的最长公共子序列的长度
但这样写不出状态转移方程,因为这里 求解公共连续字符串 是没法形成递推关系的,因此增加限制条件:
f(i, j)表示str1中前i个字符和str2中前j个字符中的最长公共子序列的长度,且以第i个字符和第j个字符为结尾
可以简单写出状态转移方程
str1[i] == str2[j] 时,f[i][j] = f[i-1][j-1] + 1
str1[i] != str2[j] 时,f[i][j] = 0
但还有个问题,这个动态规划不能直接得到答案,需要用变量maxLength保存最长的长度
边界条件为:
i = 0 或 j = 0 时, f[i][j] = 0
引自link
这里有张图:
代码:
import java.util.*;
public class Solution {
/**
* longest common substring
* @param str1 string字符串 the string
* @param str2 string字符串 the string
* @return string字符串
*/
public String LCS (String str1, String str2) {
// write code here
String res = "";
char[] s1 = str1.toCharArray();
char[] s2 = str2.toCharArray();
int l1 = str1.length();
int l2 = str2.length();
int[][] ans = new int[l1+1][l2+1];
int last1 = 0;
int max = 0;
for(int i = 1; i<=l1;i++){
for(int j=1;j<=l2;j++){
if(s1[i-1] == s2[j-1])
ans[i][j] = ans[i-1][j-1] + 1;
else
ans[i][j] = 0;
if(ans[i][j]>max){
max = ans[i][j];
last1 = i;
}
}
}
for(int i=last1-max;i<last1;i++){
res = res + s1[i];
}
return res;
}
}