leetcode每日一题 2021/4/3 1143. 最长公共子序列

简介: leetcode每日一题 2021/4/3 1143. 最长公共子序列

题目:

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

示例 1:

输入:text1 = “abcde”, text2 = “ace”

输出:3

解释:最长公共子序列是 “ace” ,它的长度为 3 。

示例 2:

输入:text1 = “abc”, text2 = “abc”

输出:3

解释:最长公共子序列是 “abc” ,它的长度为 3 。

示例 3:

输入:text1 = “abc”, text2 = “def”

输出:0

解释:两个字符串没有公共子序列,返回 0 。

提示:

1 <= text1.length, text2.length <= 1000

text1 和 text2 仅由小写英文字符组成。

来源:力扣(LeetCode

链接:https://leetcode-cn.com/problems/longest-common-subsequence

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

这是一道简单的动态规划入门题;

以 text1 = “abcde”, text2 = “ace” 为例

我们可以构建一个这样的二维数组

其中第i行和第j位的数字代表text1前i位和text2前j位的最大公共子序列,好了,我们知道了要构建这么一个二维数组,后面说到的res代表的就是该数组。但是这个数组要怎么构建起来呢?首先我们就应该要找出规律,写出它的动态转移方程。

需要分两种情况:

(1)text1[i] == text2[j]

这种情况下说明当前的元素可以是公共的元素,我们可以在text1[1 ~ (i-1)] (注:取第一位到第第i-1位)和text2[1 ~ (j-1)]的最长公共子序列的基础上加1,也就是res[i][j] = res[i-1][j-1] + 1;

(2)tex1[i] != text2[j]

这种情况下我们有两个选择

① 选择text1[1 ~ (i-1)] 和 text2[1 ~ j]的最长公共子序列

② 选择text1[1 ~ i] 和 text2[1 ~ (j-1)]的最长公共子序列

而我们要的是最优解,所以肯定要选择这两者中的最大者,也就是:

res[i][j] = max(res[i-1][j],res[i][j-1])

至此,我们已经得出了它的动态转移方程,接下来只要用代码来实现就可以了。

代码

javascript
var longestCommonSubsequence = function(text1, text2) {
    let res = new Array(text1.length + 1);
    for(let i = 0; i <= text1.length; i++){
        res[i] = new Array(text2.length + 1).fill(0);
    }
    for(let i = 1; i <= text1.length; i++){
        for(let j = 1; j <= text2.length; j++){
            if(text1[i-1] == text2[j - 1]){
                res[i][j] = res[i - 1][j - 1] + 1;
            }else{
                res[i][j] = Math.max(res[i - 1][j],res[i][j - 1]);
            }
        }
    }
    return res[text1.length][text2.length];
};
C语言
#include<string.h>
int longestCommonSubsequence(char * text1, char * text2){
    int res[1005][1005],
        n = strlen(text1),
        m = strlen(text2);
    for(int i = 0; i <= n; i++){
        res[i][0] = 0;
    }
    for(int i = 0; i <= m; i++){
        res[0][i] = 0;
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(text1[i - 1] == text2[j - 1]){
                res[i][j] = res[i - 1][j - 1] + 1;
            }else{
                res[i][j] = res[i - 1][j] > res[i][j - 1] ? res[i - 1][j] : res[i][j - 1];
            }
        }
    }
    return res[n][m];
}
python
class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m = len(text1)
        n = len(text2)
        res = [[0] * (n + 1) for i in range(m + 1)]
        for i in range(1,m+1):
            for j in range(1,n+1):
                if(text1[i - 1] == text2[j - 1]):
                    res[i][j] = res[i - 1][j - 1] + 1
                else:
                    res[i][j] = res[i - 1][j] if res[i - 1][j] > res[i][j - 1] else res[i][j - 1]
        return res[m][n]
目录
相关文章
|
6天前
|
Go
golang力扣leetcode 1143.最长公共子序列
golang力扣leetcode 1143.最长公共子序列
20 0
|
6天前
|
索引
leetcode代码记录(最长公共子序列
leetcode代码记录(最长公共子序列
8 0
|
6天前
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
40 0
|
6天前
leetcode-1143:最长公共子序列
leetcode-1143:最长公共子序列
29 0
|
6月前
|
算法
代码随想录算法训练营第五十三天 | LeetCode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和
代码随想录算法训练营第五十三天 | LeetCode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和
38 1
leetcode 1143 最长的公共子序列
leetcode 1143 最长的公共子序列
72 0
leetcode 1143 最长的公共子序列
代码随想录刷题|LeetCode 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划
代码随想录刷题|LeetCode 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划
代码随想录刷题|LeetCode 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划
[动态规划]Leetcode 1143.最长公共子序列(python)
[动态规划]Leetcode 1143.最长公共子序列(python)
[动态规划]Leetcode 1143.最长公共子序列(python)
LeetCode 动态规划之最长公共子序列
LeetCode 动态规划之最长公共子序列
120 0
LeetCode 动态规划之最长公共子序列