目录
一、最长公共子序列问题(LCS)
最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题。一个数列 ,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则称为已知序列的最长公共子序列。
1、题目
我们有两个字符串m和n,如果它们的子串a和b内容相同,则称a和b是m和n的公共子序列。子串中的字符不一定在原字符串中连续。
例如字符串“abcfbc”和“abfcab”,其中“abc”同时出现在两个字符串中,因此“abc”是它们的公共子序列。此外,“ab”、“af”等都是它们的字串。
现在给你两个任意字符串(不包含空格),请帮忙计算它们的最长公共子序列的长度。输入描述:
输入包含多组数据。 每组数据包含两个字符串m和n,它们仅包含字母,并且长度不超过1024。输出描述:
对应每组输入,输出最长公共子序列的长度。示例1
输入
abcfbc abfcab programming contest abcd mnp输出
4 2 0
2、题目解读
如题所示,题目会给我们两个字符串,要求我们去寻找最长的公共子序列。下面我举ABCBDAB和BDCABA这个例子,我们先用肉眼发现一下有三个长度都是四的子序列。
这是一个非常经典的动态规划题,我也废话不多说,接下来直接说解决这个问题最常见的方法:创建一个二维数组dp[][],用dp[i][j]来存储s1前i个字符和s2前j个字符的LCS数,我们想一下dp[i][j]和dp[i+1][j+1]有什么关系,发现 假如s1ᵢ₊₁ 字符和s2 ⱼ₊₁字符相同,则
dp[i+1][j+1]=dp[i][j]+1,如果s1ᵢ₊₁ 字符和s2 ⱼ₊₁字符不相同,则
dp[i+1][j+1]=Max(dp[i+1][j],dp[i][j+1])。可以查看下方s1和s2的dp[][]图。说到这里代码也就出来了
3、代码
import java.util.Scanner;
public class Main {
public static int MaxLength(String s1, String s2) {
int m = s1.length();
int n = s2.length();