题解 | #公共子串计算#
公共子串计算
https://www.nowcoder.com/practice/98dc82c094e043ccb7e0570e5342dd1b
import java.util.Scanner;
// mark一下 经典
// 注意和题目:HJ65 《查找两个字符串a,b中的最长公共子串》https://www.nowcoder.com/practice/181a1a71c7574266ad07f9739f791506?tpId=37&tqId=21288&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3Fdifficulty%3D3%26page%3D1%26pageSize%3D50%26search%3D%26tpId%3D37%26type%3D37&difficulty=3&judgeStatus=undefined&tags=&title=
// 如果是最长公共 子序列
// a[i] != b[j] -> dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j])
// a[i] == b[j] -> dp[i][j] = dp[i - 1][j - 1] + 1
// 字串和子序列 i == 0 || j == 0 -> dp[i][j] = 0
// 方法1更容易理解和编写
// 方法一:短字符串头尾双指针判断是否包含与长字符串中
// 方法二:动态规划 dp[i][j] :以a[i]和b[j]结尾的两个字符串的最长字串
// 递归方程:if (a[i] == b[j]) 则:dp[i][j] = dp[i - 1][j - 1] + 1
// 时刻更新最大值即可
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
String s1 = in.nextLine();
String s2 = in.nextLine();
if (s1.length() > s2.length()) {
String tmp = s1;
s1 = s2;
s2 = tmp;
}
int ans = 0;
int length = s1.length();
for (int i = 0; i < length; i++) {
for (int j = length; j > i; j--) {
String substr = s1.substring(i, j);
if (s2.contains(substr)) {
ans = Math.max(ans, j - i);
break;
}
}
}
System.out.println(ans);
}
}
}
// 方法2
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
String s1 = in.nextLine();
String s2 = in.nextLine();
int length1 = s1.length();
int length2 = s2.length();
int[][] dp = new int[length1 + 1][length2 + 1];
int ans = 0;
// dp题目 数组大小初始化为长度 遍历从1开始
for (int i = 1; i <= length1; i++) {
for (int j = 1; j <= length2; j++) {
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
ans = Math.max(ans, dp[i][j]);
}
}
System.out.println(ans);
}
}
}
查看4道真题和解析