1.题目描述
1143. 最长公共子序列
给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,”ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。
若这两个字符串没有公共子序列,则返回 0。
示例 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 <= text1.length <= 1000
1 <= text2.length <= 1000
输入的字符串只含有小写英文字符。
2.代码实现
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
| class Solution { public int longestCommonSubsequence(String text1, String text2) { //特殊情况 if (text1.length() == 0 || text2.length() == 0){ return 0; }
//存储str1对应长度子字符串和str2对应长度子字符串最长共同子序列 int[][] max_length = new int[text1.length()][text2.length()]; //System.out.println(max_length.length);
//初始化一些值 for (int i = 0; i < text1.length(); i++) { for (int j = 0; j < 1; j++) { max_length[i][j] = text1.charAt(i) == text2.charAt(j) ? 1 : 0; if (max_length[i][j] == 0 && i > 0){ max_length[i][j] = max_length[i-1][j]; } } } for (int i = 0; i < 1; i++) { for (int j = 0; j < text2.length(); j++) { max_length[i][j] = text1.charAt(i) == text2.charAt(j) ? 1 : 0; if (max_length[i][j] == 0 && j > 0){ max_length[i][j] = max_length[i][j-1]; } } }
//初始化其他位置的值 for (int i = 1; i < text1.length(); i++) { for (int j = 1; j < text2.length(); j++) { max_length[i][j] = text1.charAt(i) == text2.charAt(j) ? max_length[i-1][j-1]+1 : Math.max(max_length[i-1][j],max_length[i][j-1]); } }
return max_length[text1.length()-1][text2.length()-1]; } }
|
代码思路:
- 第一行数据分别代表B和A的最长公共子序列,BD和A的最长公共子序列,BDC和A的最长公共子序列,。。。
- 第一列数据分别代表A和B的最长公共子序列,AB和B的最长公共子序列,ABC和B的最长公共子序列,。。。
- 之后的数据需要判断当前位置是否两个对应字符是否相同。
- 不相同的情况:比如BD和AB的最长公共子序列,此时需要比较D和B是否相同,如果不相同那么就需要在B和AB的最长公共子序列和BD和A的最长公共子序列两者之间选择最大的。
- 相同的情况:比如BDC和ABC的最长公共子序列。由于C是共同的子序列,那么我们只需要找到BD和AB的最长公共子序列,BDC和ABC的最长公共子序列就是在BD和AB的最长公共子序列的基础上+1。