首页 > 其他分享 >【LeetCode动态规划#15】最长公共子序列II

【LeetCode动态规划#15】最长公共子序列II

时间:2023-08-24 23:23:48浏览次数:48  
标签:15 s2 s1 最长 II 公共 序列 LeetCode dp

最长公共子序列(二)

描述

给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如果最长公共子序列为空,则返回"-1"。目前给出的数据,仅仅会存在一个最长的公共子序列

数据范围:0≤∣���1∣,∣���2∣≤20000≤∣str1∣,∣str2∣≤2000

要求:空间复杂度 �(�2)O(n2) ,时间复杂度 �(�2)O(n2)

示例1

输入:

"1A2C3D4B56","B1D23A456A"

返回值:

"123456"
示例2

输入:

"abc","def"

返回值:

"-1"
示例3

输入:

"abc","abc"

返回值:

"abc"
示例4

输入:

"ab",""

返回值:

"-1"

思路

最长重复子数组确定dp数组含义的思路类似,本题dp数组的含义是:s1的前i个字符与s2的前j个字符的最长公共子序列的长度

当s1遍历到i - 1,s2遍历到j - 1时最长公共子序列的长度为dp[i][j]

然后使用两个指针i、j分别遍历两个字符串,

如果当前遍历值相等,那么当前位置的最长公共子序列长度一定可以由上一个位置的最长公共子序列长度加1得到;

如果当前遍历值不相等,则分别让i和j回退一位,取可以使dp数组更大的那个情况作为dp数组的更新值;

每次循环后,更新当前的dp数组的最大值到res

计算完毕dp数组后,根据dp数组去遍历s1、s2来获得输出字符串out

具体实现步骤如下:

  1. 初始化一个空字符串out,用于存储最长公共子序列。
  2. 根据动态规划的思想,从右下角开始向左上角遍历dp数组。变量ij分别表示当前遍历的位置。
  3. 如果s1[i - 1]等于s2[j - 1],说明当前字符是公共字符,将它添加到out的前面,并将ij都向左上方移动一位。
  4. 如果不相等,则比较dp[i - 1][j]dp[i][j - 1]的大小,选择较大的方向移动。如果二者相等,则优先向左移动。
  5. 重复步骤3和步骤4,直到ij为0。
  6. 返回最终得到的out字符串,即为最长公共子序列。

代码

#include <vector>
class Solution {
  public:
    string LCS(string s1, string s2) {
        vector<vector<int>> dp(s1.size() + 1, vector<int>(s2.size() + 1, 0));

        int res = 0;
        for (int i = 1; i <= s1.size(); ++i) {
            for (int j = 1; j <= s2.size(); ++j) {
                if (s1[i - 1] == s2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
                if (dp[i][j] > res) {
                    res = dp[i][j];
                }
            }
        }

        if (res == 0)
            return "-1";

        string out = "";
        int i = s1.size();
        int j = s2.size();
        while (i > 0 && j > 0) {
            if (s1[i - 1] == s2[j - 1]) {
                out = s1[i - 1] + out;
                i--;
                j--;
            } else if (dp[i - 1][j] >= dp[i][j - 1]) {
                i--;
            } else {
                j--;
            }
        }
        return out;
    }
};

dp数组值较大的方向移动是为了确保选择的路径上能够包含更多的公共字符,从而得到最长的公共子序列。

举个例子来说明计算得到的dp数组的形状:

假设s1 = "ABCBDAB"s2 = "BDCAB",则dp数组的形状如下所示:

    B  D  C  A  B
A   0  0  0  1  1
B   1  1  1  1  2
C   1  1  2  2  2
B   1  1  2  2  3
D   1  2  2  2  3
A   1  2  2  3  3
B   1  2  2  3  4

dp[i][j]表示s1的前i个字符与s2的前j个字符的最长公共子序列的长度。根据题目要求,我们希望得到最长的公共子序列,因此,在遍历时如果当前字符相等,就选择左上方对角线上的值加1,表示当前字符也属于公共子序列;如果不相等,则选择左方或上方较大的值,表示忽略当前字符。

在这个例子中,dp[7][5]的值为4,表示s1的前7个字符与s2的前5个字符的最长公共子序列的长度为4。通过回溯路径,我们可以得到最长公共子序列为"BCBA"。

在计算out字符串时,根据上述例子,从右下角开始,按照选择的方向移动,即可得到最长公共子序列"BCBA"。

标签:15,s2,s1,最长,II,公共,序列,LeetCode,dp
From: https://www.cnblogs.com/DAYceng/p/17655445.html

相关文章

  • 代码随想录第二天|977.有序数组的平方;209.长度最小的子数组;59.螺旋矩阵II,总结
    今天的这三道题每道题对我来说都不简单,有序数组的平方和长度最小的子数组这两道题还能用暴力求解,螺旋矩阵看着简单却没有思路,磨了半小时还是决定直接看讲解有序数组平方和用的双指针的思想,代码如下:1classSolution{2public:3vector<int>sortedSquares(vector<int......
  • 1155 Heap Paths
    Incomputerscience,a heap isaspecializedtree-baseddatastructurethatsatisfiestheheapproperty:ifPisaparentnodeofC,thenthekey(thevalue)ofPiseithergreaterthanorequalto(inamaxheap)orlessthanorequalto(inaminheap)......
  • 15. 负债 Liabilities
    Theobligationtopay偿还的义务一般,以一年内是不是需要偿还,分为短期负债和长期负债1.短期负债CurrentLiabilities1.1应付账款AccountsPayable中应付供应商的货款。1.2应付票据NotesPayable如银行贷款,它及其以后每月产生的利息,做以下记账:1.3应付利息Interest......
  • 洛谷100题计划 (15/100)
    洛谷100题计划(15/100)P1094[NOIP2007普及组]纪念品分组-洛谷|计算机科学教育新生态(luogu.com.cn)要使得分组最少,其实就是要让一个大的和一个小的放一起,如果大的和小的一起放超过了\(w\),那大的就应该单独放,所以排完序之后,我们可以用双指针从两边寻找可以放一起的......
  • 【LeetCode1】统计参与通信的服务器
    【题目】这里有一幅服务器分布图,服务器的位置标识在m*n的整数矩阵网格grid中,1表示单元格上有服务器,0表示没有。如果两台服务器位于同一行或者同一列,我们就认为它们之间可以进行通信。请你统计并返回能够与至少一台其他服务器进行通信的服务器的数量。【示例一】......
  • 微服务引擎 MSE 全新升级,15 分钟快速体验微服务全栈能力
    作者:草谷前言微服务引擎MSE全新发布!新版本带来了一系列令人振奋的特性和改进,让您更轻松、高效地构建和管理微服务应用程序。从快速入门到迁移优化,MSE为开发人员提供了全方位的支持和解决方案。无论您是刚刚接触微服务还是已经深耕其中,MSE都将为您带来独特的体验和突破。让我......
  • Leetcode——1957、删除字符使字符串变好
    一个字符串如果没有 三个连续 相同字符,那么它就是一个 好字符串 。给你一个字符串 s ,请你从 s 删除 最少 的字符,使它变成一个 好字符串 。请你返回删除后的字符串。题目数据保证答案总是 唯一的 。 示例1:输入:s="leeetcode"输出:"leetcode"解释:从第一组'......
  • Leetcode 1. 两数之和(Two sum)
    题目链接......
  • IIS发布自动回收等问题
     一、自动回收问题,应用程序池配置(两个都需配置)1、闲置时间间隔设置为02、闲置超时设置为0 参考:http://bibaoke.com/post/66http://furion.baiqian.ltd/docs/deploy-iis#3415-iis-%E5%9B%9E%E6%94%B6%E9%97%AE%E9%A2%98%E5%92%8C%E9%85%8D%E7%BD%AE  二、接口Delete/P......
  • P1507 NASA的食物计划
    有n种候选食物,且只有一样,分别给出对应食物的体积、质量、卡路里飞船空间和载重都有限,分别为v和m,求能承载食物的最大卡路里1.动态规划voidmaxval(intv,intm,vector<int>&weight,vector<int>&volume,vector<int>&w){intn=w.size();intdp[v+1][m+1];memse......