LeetCode_139_LongestCommonSubsequence


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]结尾的两个数组构成的最长子序列长度。显然状态由下组成:

  1. 如果A[i]=B[j],即dp[i][j]=dp[i-1][j-1] + 1,因为二者相同,显然子序列中使用了本元素,那么只能由前面的元素组成的数组中的子序列状态转移过来。
  2. 如果不相等,即此时本元素不会构成子序列,那么可能就是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";

// String text1 = "abc";
// String text2 = "def";

// String text1 = "ezupkr";
// String text2 = "ubmrapg";

System.out.println(s.longestCommonSubsequence(text1, text2));
}
}

3. 备注

参考力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 (leetcode-cn.com)代码随想录 (programmercarl.com)


文章作者: 浮云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 浮云 !
  目录