有点难受,网上看的思路都是dp表,后面终于把递归思路摸出来
注意,可以改写dp表,效率应该会更好
import java.util.Scanner;
/**
* @author 罗有冠
* @date 2022/10/14 0:36
*/
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String string1 = scanner.next();
String string2 = scanner.next();
// 最大长度
int max = 0;
// 这个用来标记最长的起点,到最后要输出出来
int ansi = 0;
// 备忘录
int[][] memory = new int[string1.length()][string2.length()];
for (int i = 0; i < string1.length(); i++) {
for (int j = 0; j < string2.length(); j++) {
// 计算以i,j为起点的最长公共子串的最大长度
int curAns = recursion(string1.toCharArray(), i, string2.toCharArray(), j, memory);
// 如果最大长度比max大,替换
if (curAns > max) {
max = curAns;
ansi = i;
}
}
}
System.out.print(max + "\n");
System.out.print(string1.substring(ansi, ansi + max));
}
// 递归
static int recursion(char[] s1, int i, char[] s2, int j, int[][] memory) {
// 如果有一个走到了尽头,返回0
if (i == s1.length || j == s2.length) {
return 0;
}
// 如果备忘录记过了,直接返回
if (memory[i][j] != 0) {
return memory[i][j];
}
// 如果s1[i] == s2[j],那么再往两字符串下一格探
if (s1[i] == s2[j]) {
memory[i][j] = 1 + recursion(s1, i + 1, s2, j + 1, memory);
} else {
// s1[i] != s2[j],返回0
memory[i][j] = 0;
}
return memory[i][j];
}
}```