Leetcode 1143.最长公共子序列(720)

题目

26年7月20日(首刷看解)

Go 复制代码
func longestCommonSubsequence(text1 string, text2 string) int {
    //dp[i][j],表示tset1[0~i-1]和text2[0~j-1]的最长公共子序列的长度
    dp:=make([][]int,len(text1)+1)
    for i,_ :=range dp{
        dp[i]=make([]int,len(text2)+1)
    }   
    for i:=1;i<=len(text1);i++{
        for j:=1;j<=len(text2);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[len(text1)][len(text2)]
    //这道题需要演算一下例子
}

思路

这里变成求非连续的相同序列,和连续属于两种题型

非连续的dp数组定义是dp[i][j],表示text1[0~i-1]text2[0~j-1]的最长公共子序列的长度,总之这一次不是以某一个元素结尾,而是从0一直到当前这个数字考虑。主要原因就是非连续,意味着只保持相对顺序,可以跳过元素。

那么递推公式有两种情况

第一种:当前这一对匹配

那么沿用之前连续时的递推公式dp[i][j]=dp[i-1][j-1]+1

第二种:当前这一对不匹配

当前这一对不匹配,不意味着断开了要重新计算了,因为可以从之前的位置继续找,

当前的i与j不匹配,但是当前的i可能和j之前的0~j-1,是一样的

也有可能j和i之前的0~i-1是相同的,这些都是满足要求的

所以递推公式dp[i][j]=max(dp[i-1][j],dp[i][j-1])

看到这个递推公式其实我也会后来想,如果dpi-1j或者dpij-1也是不匹配呢?仍然是默认的0?

其实总有一对他是匹配的,匹配后的长度值会不断的挨着传递,不用担心这个问题。

所以把两种情况合起来就是完整的递推公式

最后返回值,注意我们的dp数组含义已经发生变化 ,这里不再需要维护最大值,因为最大值一直在dp之间从前往后传递,所以返回dp[len(text1)][len(text2)]没问题

相关推荐
掘金者阿豪18 小时前
一条SQL能执行成功,不代表它真的安全:一次生产环境数据库迁移事故复盘
后端
Reart18 小时前
Leetcode 718.最长重复子数组(720)
后端
云上小朱18 小时前
软件更新-openssh和openssl-centos
后端
无相求码18 小时前
const vs #define:C语言常量定义的差异
c语言·算法
Conan在掘金18 小时前
鸿蒙 ArkUI 深水区:Navigation 多级路由,从「拼页面」到「搭应用」的分水岭
后端
千纸鹤安安18 小时前
如何看待 Go 1.18 引入的泛型?对 Go 开发者来说是必须掌握的吗?
后端
颜进强18 小时前
Claude Code -21 Agent 规划化编写范式
前端·后端
先吃饱再说18 小时前
LeetCode 226. 翻转二叉树
算法
剑锋所指,所向披靡!19 小时前
数据结构之关键路径
数据结构·算法