给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
输入:text1 = “abcde”, text2 = “ace”
输出:3
解释:最长公共子序列是 “ace” ,它的长度为 3 。
输入:text1 = “abc”, text2 = “abc”
输出:3
解释:最长公共子序列是 “abc” ,它的长度为 3 。
输入:text1 = “abc”, text2 = “def”
输出:0
解释:两个字符串没有公共子序列,返回 0 。
对于两个子序列 S1S1S1 和 S2S2S2,找出它们最长的公共子序列。
定义一个二维数组 dp 用来存储最长公共子序列的长度,其中 dp[i][j] 表示 S1S1S1 的前 i 个字符与 S2S2S2 的前 j 个字符最长公共子序列的长度。考虑 S1iS1_iS1i与 S2jS2_jS2j 值是否相等,分为两种情况:
综上,最长公共子序列的 状态转移方程 为:
dp[i][j]={dp[i−1][j−1]+1S1i==S2jmax(dp[i−1][j],dp[i][j−1])S1i<>S2jd p[i][j]=\left\{\begin{array}{rr} d p[i-1][j-1]+1 & S 1_{i}==S 2_{j} \\ \max (d p[i-1][j], d p[i][j-1]) & S 1_{i}<>S 2_{j} \end{array}\right.dp[i][j]={dp[i−1][j−1]+1max(dp[i−1][j],dp[i][j−1])S1i==S2jS1i<>S2j
对于长度为 m 的序列 S1 和长度为 n 的序列 S2,dp[m][n] 就是序列 S1 和序列 S2 的最长公共子序列长度。
与最长递增子序列 相比,最长公共子序列有以下不同点:
public class LongestCommonSubsequence {public static void main(String[] args) {// TODO Auto-generated method stubString text1 = "abcde";String text2 = "ace";System.out.println(longestCommonSubsequence(text1,text2));}public static int longestCommonSubsequence(String text1, String text2) {int m = text1.length();int n = text2.length();int[][] dp = new int[m + 1][n + 1];for(int i = 1; i <= m; i++) {for(int j = 1; j <= n; j++) {if(text1.charAt(i - 1) == text2.charAt(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]);}}}return dp[m][n];}
}
题目来源:力扣。
上一篇:【C语言】指针的深度理解(一)