1. question: 最长公共子序列(中等)
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,”ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-common-subsequence
示例 1:
1 2 3
| 输入:text1 = "abcde", text2 = "ace" 输出:3 解释:最长公共子序列是 "ace" ,它的长度为 3 。
|
示例 2:
1 2 3
| 输入:text1 = "abc", text2 = "abc" 输出:3 解释:最长公共子序列是 "abc" ,它的长度为 3 。
|
示例 3:
1 2 3
| 输入:text1 = "abc", text2 = "def" 输出:0 解释:两个字符串没有公共子序列,返回 0 。
|
提示:
1 2
| 1 <= text1.length, text2.length <= 1000 text1 和 text2 仅由小写英文字符组成。
|
2. answers
这道题要求是公共子序列,即允许不连续。而且不要求递增,所以无需比较前面的所有子序列。可采用动态规划的思路来做。定义数组dp[i][j]表示当前以A[i]和B[j]结尾的两个数组构成的最长子序列长度。显然状态由下组成:
- 如果A[i]=B[j],即dp[i][j]=dp[i-1][j-1] + 1,因为二者相同,显然子序列中使用了本元素,那么只能由前面的元素组成的数组中的子序列状态转移过来。
- 如果不相等,即此时本元素不会构成子序列,那么可能就是A[i-1]和B[j]或者A[i]和B[j-1]两种情况构成的子序列,那么
dp[i][j]=Max(dp[i-1][j], dp[i][j-1])
。
代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| public class Solution_0139 {
public int longestCommonSubsequence(String text1, String text2) {
int[][] dp = new int[text1.length()][text2.length()];
if(text1.charAt(0) == text2.charAt(0)) dp[0][0] = 1;
for (int i = 1; i < text1.length(); i++) { if(text2.charAt(0) == text1.charAt(i)) { dp[i][0] = 1; } else { dp[i][0] = dp[i-1][0]; } }
for (int i = 1; i < text2.length(); i++) { if(text1.charAt(0) == text2.charAt(i)) { dp[0][i] = 1; } else { dp[0][i] = dp[0][i-1]; } }
for (int i = 1; i < text1.length(); i++) {
for (int j = 1; j < text2.length(); j++) {
if(text1.charAt(i) == text2.charAt(j)) { dp[i][j] = dp[i-1][j-1] + 1; } else { dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]); } } }
for (int i = 0; i < dp.length; i++) {
for (int j = 0; j < dp[i].length; j++) {
System.out.print(dp[i][j] + "\t"); } System.out.println(); }
return dp[text1.length() - 1][text2.length() - 1]; }
public static void main(String[] args) { System.out.println();
Solution_0139 s = new Solution_0139();
String text1 = "abcde"; String text2 = "ace";
System.out.println(s.longestCommonSubsequence(text1, text2)); } }
|
3. 备注
参考力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 (leetcode-cn.com),代码随想录 (programmercarl.com)。