前言
仅记录学习笔记,如有错误欢迎指正。
题目一
给定两个字符串s1,s2,输出两个字符串的最长公共子串。题目二
给定两个字符串s1,s2,输出两个字符串的最长公共子序列。
示例
- 输入: “1ab2345cd”,“12345ef”
- 输出: “2345” (子串)
- 输出: “12345” (子序列)
解法一
子串: /**
* 获取 str1和str2的最长公共子串
* 1ab2345cd 12345ef === 2345
*
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s1 = in.nextLine();
String s2 = in.nextLine();
if(s1.length() > s2.length()){
String temp = s1;
s1 = s2;
s2 =temp;
}
int m = s1.length();
int n = s2.length();
int[][] dp = new int[m+1][n+1];
int max = 0;
String res = "";
for(int i = 1;i<= m ;i++){
for(int j = 1 ; j<= n;j++){
if(s1.charAt(i-1) == s2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1]+1;
if(dp[i][j] > max){
max = Math.max(max,dp[i][j]);
res = s1.substring(i-max,i);
}
}
}
}
System.out.println(res);
}
解法二
子序列
/**
* s1 s2的最长的公共子序列
*
*/
public static String function(String s1, String s2) {
int m = s1.length();
int n = s2.length();
//以i j结尾的s1,s2 所最长的公共子序列
String[][] dp = new String[m + 1][n + 1];
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
if (i == 0 || j == 0) {
dp[i][j] = "";
} else if (s1.charAt(i-1) == s2.charAt(j-1)) {
dp[i][j] = dp[i - 1][j - 1] + s1.charAt(i-1);
} else {
dp[i][j] = dp[i][j - 1].length() > dp[i - 1][j].length() ?
dp[i][j - 1] : dp[i - 1][j];
}
}
}
return dp[m][n];
}