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)]没问题

相关推荐
揽星河..3 分钟前
【C语言】分支和循环
c语言·c++·算法
考虑考虑1 小时前
瀚高数据库
数据库·后端·postgresql
Fuyo_11192 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
锋行天下2 小时前
DeepSeek写Langgraph就是个大傻逼,一本正经胡说八道
前端·人工智能·后端
jktantan2 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
揽星河..2 小时前
【C语言】猜数字游戏
c语言·算法·游戏
LabVIEW开发3 小时前
CTM-3 红外测温仪 + LabVIEW 温度怎么测?
算法·labview·测试·labview程序
纪念 2293 小时前
C++算法(六)
开发语言·c++·算法
小小张说故事3 小时前
Python 的 str 为什么设计成不可变?拆开字符串驻留、字符串池,以及 += 拼接到底慢在哪
后端·python
AI架构师之家4 小时前
我把 Hermes 这匹"马"养了两周,它干了一件让我有点发毛的事
后端