[路飞]-leetcode1143. 最长公共子序列

178 阅读1分钟

我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

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

考虑动态规划来做:

  • 每个动态规划都可以考虑用网格来做
  • 每个单元格都是我们拆解的一个子问题,每个单元格的值记录你的优化解。
  • 单元格也有助于你找到坐标抽。 解题步骤:
  • 我们需要一个dp数组来记录当前索引的公共子序列长度;
  • 如果s1==s2时;s1,s2分别代表的是两个比较字符串的单个字符,当前索引dp[i][j]的公共子序列就是之前的dp[i-1][j-1] + 1;
  • 否则:当前索引的公共子序列,有两种情况dp[i][j-1], dp[i-1][j], 我们需要取他的最大值。

我们通常声明的dp是一个二维数组new Array(m+1).fill(0).map(()=> new Array(n+1).fill(0)) 我们当前索引的长度时靠上一个索引长度基础上加1,所以我们得防止索引出现负值。

// m为s1的字符串长度 n为s2的字符串长度
// 如果不存在返回0 , 所以我们初始化数组的值都为0
let dp = new Array(m+1).fill(0).map(()=> new Array(n+1).fill(0))
let t1, t2;
for(let i = 1; i<=m ; i++){
    t1 = s1[i-1]
    for(let j = 1; j<=n; j ++){
        t2 = s2[j-1]
        if(t1 == t2){
            dp[i][j] = dp[i-1][j-1] + 1
        }else{
            //这里记录字符串比对不同时,将结果往后顺延
            // 当前也可以不做 在循环结束之后 直接取dp的最大值 二维的数组取的比较麻烦 还是记录更佳
            dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1])
        }
    }
}
return dp[m][n] // 返回的最后一个元素就是我们想要的结果

好啦,最长公共子序列的讲解都到此结束了。

结束语

如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~