题目描述
给定两个字符串,寻找这两个字串之间的最长公共子序列。
输入
输入两行,分别包含一个字符串,仅含有小写字母。
输出
最长公共子序列的长度。
样例输入
abcdgh
aedfhb
样例输出
3
解法:动态规划
思路:
1. 确定dp数组表示什么:dp[i][j]指,string1[0到i]组成的字符串与string2[0到j]组成的字符串的最长公共序列
2. 找递推关系,分两种情况:
第一种,如果string1[i - 1] == string2[j - 1],那么最长公共子序列长度当然得 + 1,dp[i] [j] = dp[i - 1] [j - 1] + 1;
第二种,如果String1[i - 1] != String2[j - 1],那么最长公共子序列长度为以下两种情况的最大值:
【1】string1[0到(i – 1)]和string2[0到j]的最长公共子序列长度
【2】string1[0到i]和string2[0到(j – 1)]的最长公共子序列长度
所以找到的递推式为:
3. 初始化数组
这一步就是寻找已知的dp元素值,显然string1的前0个字符组成的字符串和string2的前j个字符串没有子序列,所以dp[0] [i] = 0,同理有dp[i] [0] = 0,还有一个特殊点,dp[0] [0]= 0;
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String string1 = scanner.nextLine();
String string2 = scanner.nextLine();
int len1 = string1.length();
int len2 = string2.length();
char str1Array[] = string1.toCharArray();
char str2Array[] = string2.toCharArray();
int[][] dp = new int[1001][1001];
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (str1Array[i - 1] == str2Array[j - 1]) {
dp[i][j] = 1 + dp[i - 1][j - 1];
} else {
dp[i][j] = dp[i - 1][j] > dp[i][j - 1] ? dp[i - 1][j] : dp[i][j - 1];
}
}
}
System.out.println(dp[len1][len2]);
}
}