leetcode 1143.最长公共子序列

本文介绍了如何将动态规划应用于解决字符串的二维问题,以求解text1和text2之间的最长公共子序列。通过构建dp[i][j]数组,文章详细阐述了状态转移方程,并给出了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:动态规划的二维问题。

我们这里并不能仅限于把dp看作就是一维的了。dp也可以是二维的,这里就是一个例子,其实这里以字符为尾的数组,你发现只能对于一个数组进行遍历,而不能同时对于两个数组进行遍历。 这里就需要我们开二维数组进行解决了。

dp[i][j]代表的就是对于text1[i]的[0,i-1]区间与text2[j]的[0,j-1]区间的最长公共子序列的长度。这样就顾及到第二个数组里面的东西了。OK,那么我们开始推状态方程。

假如我们以最后一个字符为尾为例,这个时候,如果说循环遍历到的目前这个i,j字符,text1[i]==text2[j],那么就说明了我们当前遍历到的字符相同,可以是公共序列里面的一个元素,所以在前面已经递推的基础上+1,总体来写也就是dp[i][j]=dp[i-1][j-1]+1.

那如果不相同呢?那我们就开始找前面已经递推过来的状态了,dp[i-1][j]与dp[i][j-1]。为什么需要找这两个呢?我们想,刚刚第一种情况,我们把这两个字符的位置全部倒退了一步,但是在这里我们为什么要分开倒退呢?只倒退第一个,可能当前的字符和第一个字符串倒退后的位置的字符是相同的。同理,如果第二个字符倒退一步,那可能第二个字符串当前指向的字符位置和第一个字符串目前的字符是相同的。

所以,状态方程就成了:

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int dp[1010][1010];
        memset(dp,0,sizeof dp);
        int n1=text1.size();
        int n2=text2.size();
        for(int i=1;i<=n1;i++){
            for(int j=1;j<=n2;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[n1][n2];
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值