题目链接
给定两个长度分别为N和M的字符串A和B,求既是A的子序列又是B的子序列的字符串长度最长是多少。
输入格式
第一行包含两个整数N和M。
第二行包含一个长度为N的字符串,表示字符串A。
第三行包含一个长度为M的字符串,表示字符串B。
字符串均由小写字母构成。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤1000,
输入样例:
4 4
abcd
becd
输出样例:
3(bcd)
解题思路
dp[i][j] := A1…Ai 和 B1…Bj对应的LCS的长度.
由此,A1…Ai 和 B1…Bj对应的公共子序列可能是
- 当A(i+1) = B(j+1)时,在A1…Ai 和 B1…Bj的的公共子序列末尾追加上A(i+1)
- A1…A(i+1) 和 B1…Bj 的公共子序列
- A1…A(i+1) 和 B1…B(j+1)的公共子序列
三者中的某一个,有如下的递推关系成立
dp[i+1][j+1] = max(dp[i][j] + 1, dp[i+1][j], dp[i][j+1]) // A(i+1) = B(j+1)
p[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]) // A(i+1) != B(j+1)
时间复杂度:O(N*M) , dp[n][m] 即为LCS的长度
用二维矩阵模拟题目的例子如下: dp数组的变化过程
import java.util.Scanner;
public class Main{
public static void main(String[] agrs){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
char str1[]=sc.next().toCharArray();
char str2[]=sc.next().toCharArray();
int[][] dp=new int[n+1][m+1];
dp[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(str1[i-1]==str2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
}
}
}
System.out.println(dp[n][m]);
}
}
来源:CSDN
作者:ACMER.
链接:https://blog.csdn.net/weixin_43588422/article/details/104060727