import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
String t = in.nextLine();
int m = s.length();
int n = t.length();
int[][] dp = new int[m + 1][n + 1];
List<int[]> candidates = new ArrayList<>();
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s.charAt(i - 1) == t.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
if (dp[i][j] > 0) {
int len = dp[i][j];
int sStart = i - len;
int tStart = j - len;
candidates.add(new int[] {len, sStart, tStart});
}
} else {
dp[i][j] = 0;
}
}
}
if (candidates.isEmpty()) {
System.out.println("");
return;
}
int maxLen = 0;
for (int[] candidate : candidates) {
if (candidate[0] > maxLen) {
maxLen = candidate[0];
}
}
List<int[]> maxCandidates = new ArrayList<>();
for (int[] candidate : candidates) {
if (candidate[0] == maxLen) {
maxCandidates.add(candidate);
}
}
String shortStr = (s.length() <= t.length()) ? s : t;
int minStart = Integer.MAX_VALUE;
String result = "";
for (int[] candidate : maxCandidates) {
int currentStart;
if (shortStr.equals(s)) {
currentStart = candidate[1];
} else {
currentStart = candidate[2];
}
if (currentStart < minStart) {
minStart = currentStart;
if (shortStr.equals(s)) {
result = s.substring(candidate[1], candidate[1] + candidate[0]);
} else {
result = t.substring(candidate[2], candidate[2] + candidate[0]);
}
}
}
System.out.println(result);
}
}
https://www.nowcoder.com/discuss/727521113110073344
思路:
- 输入处理:读取两个字符串 s 和 t。
- 动态规划表初始化:创建一个二维数组 dp 来存储最长公共子串的长度。
- 填充动态规划表:遍历两个字符串,当字符相等时更新 dp 的值,并记录所有可能的公共子串信息。
- 收集候选子串:将每个公共子串的长度及其起始位置存入列表。
- 确定最长子串:找到最长公共子串,并根据较短字符串中的起始位置选择最早出现的子串。
- 输出结果:打印最长公共子串。



京公网安备 11010502036488号