vlambda博客
学习文章列表

【LCS算法#1】【二维动态规划#7】【C++】LeetCode#64 1143.最长公共子序列 Medium

This browser does not support music or audio playback. Please play it in Weixin or another browser.

1143.Longest Common Subsequence
Given two strings text1 and text2, return the length of their longest common subsequence. If there is no common subsequence, return 0.

A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.

For example, "ace" is a subsequence of "abcde". 

A common subsequence of two strings is a subsequence that is common to both strings.


Example 1:

Input: text1 = "abcde", text2 = "ace" 

Output: 3

Explanation: The longest common subsequence is "ace" and its length is 3. 


Example 2:

Input: text1 = "abc", text2 = "abc" 

Output: 3 

Explanation: The longest common subsequence is "abc" and its length is 3. 


Example 3:

Input: text1 = "abc", text2 = "def" 

Output: 0 

Explanation: There is no such common subsequence, so the result is 0.


Constraints:

  • 1 <= text1.length, text2.length <= 1000
  • text1 and text2 consist of only lowercase English characters.

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 仅由小写英文字符组成。


「题解」

1、状态:dp[i][j] -- 以text1的子串[0,i]和text2的子串[0,j]的最长公共序列 

2、起始条件base case:索引为0的行列表示空串,dp[0][...]和dp[...][0]都为0,即矩阵的左边和上边都为0

for (int i = 0; i <= len1; ++i)
    dp[i][0] = 0;
for (int j = 0; j <= len2; ++j)
    dp[0][j] = 0;

3、状态转移方程:

if (text1[i - 1] == text2[j - 1])
    dp[i][j] = dp[i - 1][j - 1] + 1;
else
    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 


「边界细节」

为了避免i-1,j-1不合法,一开始创建的dp二维数组比字符串size+1,长len1+1,宽len2+1,后续遍历时i和j都从1开始


「AC代码」

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) 
    
{
        int len1 = text1.size();
        int len2 = text2.size();
        vector<vector<int>> dp(len1 + 1vector<int>(len2 + 10))// 构建并初始化二维数组,长宽都要各自比原来长度多1,用来放初始值0
        // 边界条件
        for (int i = 0; i <= len1; ++i)
            dp[i][0] = 0;
        for (int j = 0; j <= len2; ++j)
            dp[0][j] = 0;
        // 状态转移方程
        for (int i = 1; i <= len1; ++i)
        {
            for (int j = 1; j <= len2; ++j)
            {
                if (text1[i - 1] == text2[j - 1]) 
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                else
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 
            }
        }
        return dp[len1][len2];
    }
};


「复杂度」

时间复杂度O(mn),空间复杂度O(mn)





This browser does not support music or audio playback. Please play it in Weixin or another browser.