两个字符串的最长公共子序列长度_动态规划 -- 最长公共子序列

最长公共子序列(Longest Common Subsequence, 简称 LCS)是非常经典的二维动态规划,大部分比较困难的字符串问题都和这个问题一个套路,穷举+剪枝

思路:

第一步 要明确 dp 数组的含义

对于两个字符串的动态规划问题,一般都需要一个二维的 dp 数组

其中 dp[i][j] 的含义是:对于 string1[0, ......, i-1] 和 string2[0, ......, j-1],它们的最长公共子序列长度是 dp[i][j]

比如对于字符串 string1="abcde" string2="aceb"

一般要构造这样的 DP 表

ab991c9a392623310d31ce266ee5e496.png

dp[2][4] = 2 的含义就是: 对于 "ac" 和 "babc",它们的LCS长度是 2

如果想自己练习填写动态规划表格,可以在这里练习动态规划表格练习地址

根据这个定义,最终想得到的答案应该是 dp[3][6]

第二步 定义 base case

让索引为 0 的行和列表示空串,dp[0][…] 和 dp[...][0] 都应该初始化为 0, 这就是 base case

第三步 状态转移方程

这个问题具体是求 string1 和 string2 的最长公共子序列 LCS,对于 string1 和 string2 中的每一个字符,有两种选择:要么在 LCS 中,要么不在。

如何知道 string1[i] 和 string2[j] 是否在 LCS 中?

【留坑以后填之我看懂了但还不会解释】

(function(){
    var longestCommonSubsequence = function (text1, text2) {
    const m = text1.length;
    const n = text2.length;

    // dp数组m+1行n+1列,初始化为0,此时基础情况dp[0][...] 和 dp[...][0]也一并初始化为0
    const dp = Array.from(Array(m+1), () => Array(n+1).fill(0));
    console.log(dp);

    for(let i = 1; i <= m; i++){
        for(let j = 1; j <= n; j++){
            if(text1[i - 1] == text2[j -1]){
                dp[i][j] = dp[i -1][j -1] + 1;
            } else {
                dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]);
            }
        }
    }
    return dp[m][n];
};

longestCommonSubsequence("abcde", "ace")
}())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值