[Algorithm][动态规划][两个数组的DP][最长公共子序列][不相交的线][不同的子序列][通配符匹配]详细讲解

目录

  • 1.最长公共子序列
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.不相交的线
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 3.不同的子序列
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 4.通配符匹配
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


1.最长公共子序列

1.题目链接

  • 最长公共子序列

2.算法原理详解

  • 本题很重要,可以说是本子专题的模板题了
  • 思路
    • 确定状态表示 -> dp[i][j]的含义

      • 选取第一个字符串[0, i]区间以及第二个字符串[0, j]区间作为研究对象
      • dp[i]j]s1[0, i]区间以及s2[0, j]区间内所有的子序列中,最长公共子序列的长度
    • 推导状态转移方程:根据最后一个位置的情况,分情况讨论
      请添加图片描述

    • 初始化:

      • 多开一行及一列虚拟结点
      • s1 = " " + s1, s2 = " " + s2 --> 便于下表对应
    • 确定填表顺序:从上往下,从左往右

    • 确定返回值:dp[n][m]


3.代码实现

int longestCommonSubsequence(string s1, string s2) 
{
    int n = s1.size(), m = s2.size();
    s1 = " " + s1, s2 = " " + s2;

    vector<vector<int>> dp(n + 1, vector<int>(m + 1));
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(s1[i] == s2[j])
            {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            }
            else
            {
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }

    return dp[n][m];
}

2.不相交的线

1.题目链接

  • 不相交的线

2.算法原理详解

  • 分析:本题不相交的线,其实模型就是最长公共子序列,所以可以转化模型
  • 思路
    • 确定状态表示 -> dp[i][j]的含义

      • dp[i]j]n1[0, i]区间以及n2[0, j]区间内所有的子序列中,最长公共子序列的长度
    • 推导状态转移方程:根据最后一个位置的情况,分情况讨论
      请添加图片描述

    • 初始化:多开一行及一列虚拟结点

    • 确定填表顺序:从上往下,从左往右

    • 确定返回值:dp[n][m]


3.代码实现

int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) 
{
    int n = nums1.size(), m = nums2.size();
    vector<vector<int>> dp(n + 1, vector<int>(m + 1));

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(nums1[i - 1] == nums2[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[n][m];
}

3.不同的子序列

1.题目链接

  • 不同的子序列

2.算法原理详解

  • 思路
    • 确定状态表示 -> dp[i][j]的含义

      • dp[i]j]s[0, j]区间内所有的子序列中,有多少个t[0, i]区间的子串
    • 推导状态转移方程:根据s的子序列的最后一个位置包不包含s[j]

      • dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1]
        请添加图片描述
    • 初始化:

      • 多开一行及一列虚拟结点
      • 第一行初始化为1
      • 第一列初始化为0
    • 确定填表顺序:从上往下,从左往右

    • 确定返回值:dp[m][n]


3.代码实现

int numDistinct(string s, string t) 
{
    const int MOD = 1e9 + 7;
    int n = s.size(), m = t.size();
    vector<vector<long long>> dp(m + 1, vector<long long>(n + 1));

    // Init
    for(int i = 0; i <= n; i++)
    {
        dp[0][i] = 1;
    }

    // DP
    for(int i = 1; i <= m; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            dp[i][j] += dp[i][j - 1] % MOD;
            if(t[i - 1] == s[j - 1])
            {
                dp[i][j] += dp[i - 1][j - 1] % MOD;
            }
        }
    }

    return dp[m][n];
}

4.通配符匹配

1.题目链接

  • 通配符匹配

2.算法原理详解

  • 思路
    • 确定状态表示 -> dp[i][j]的含义

      • dp[i]j]p[0, j]区间内的子串能否匹配s[0, i]区间内的子串
    • 推导状态转移方程:根据最后一个位置的情况,分情况讨论

      • 本题若直接按照如下的状态转移方程去写,时间复杂度会到 O ( N 3 ) O(N^3) O(N3)
      • 所以需要想办法优化
        请添加图片描述
    • 优化

      • 方法一:数学推导
        请添加图片描述

      • 方法二:根据状态表示以及实际情况,优化状态转移方程 -> 抽象,难理解:(

        • 实际相当于保留了*,把状态传递给前面
          请添加图片描述
    • 初始化:

      • 多开一行及一列虚拟结点
        ![[Pasted image 20240504212026.png]]
    • 确定填表顺序:从上往下,从左往右

    • 确定返回值:dp[n][m]


3.代码实现

bool isMatch(string s, string p) 
{
    int n = s.size(), m = p.size();
    s = " " + s, p = " " + p;
    vector<vector<bool>> dp(n + 1, vector<bool>(m + 1));

    // Init
    dp[0][0] = true;
    for(int i = 1; i <= m; i++)
    {
        if(p[i] == '*')
        {
            dp[0][i] = true;
        }
        else
        {
            break;
        }
    }

    // DP
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(p[j] == '*')
            {
                dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
            }
            else
            {
                dp[i][j] = (p[j] == '?' || s[i] == p[j]) && dp[i - 1][j - 1];
            }
        }
    }

    return dp[n][m];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/683286.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

读AI未来进行式笔记04数字医疗与机器人

1. 数字医疗 1.1. 20世纪的“现代医学”得益于史无前例的科学突破&#xff0c;使得医疗的方方面面都得到改善&#xff0c;让人类预期寿命从1900年的31岁提高到2017年的72岁 1.2. 现有的医疗数据库和流程将实现数字化 1.2.1. 患者记录 1.2.…

[flutter]一键将YAPI生成的api.json文件转为需要的Dart Model类的脚本

目的&#xff1a; 根据YAPI接口平台生成的api.json接口文件&#xff0c;将接口数据转化为model类&#xff0c;生成对应的接口值类型文件。 发现&#xff1a; api.json文件导出&#xff1a; YAPi是一个接口管理平台&#xff0c;登录账号打开项目后&#xff0c;在点击数据管理…

AJAX 跨域

这里写目录标题 同源策略JSONPJSONP 是怎么工作的JSONP 的使用原生JSONP实践CORS 同源策略 同源&#xff1a; 协议、域名、端口号 必须完全相同、 当然网页的URL和AJAX请求的目标资源的URL两者之间的协议、域名、端口号必须完全相同。 AJAX是默认遵循同源策略的&#xff0c;不…

275 基于matlab的脉搏信号处理GUI界面编程

基于matlab的脉搏信号处理GUI界面编程&#xff0c;并实现滤波、去噪、实时回放、小波分析 计算脉率。采用低通滤波器&#xff0c;计算巴特沃斯数字滤波器的阶数N和截止频率Wn、使用coif4小波基计算信号的平稳小波分解完成降噪。程序已调通&#xff0c;可直接运行。 275 脉搏信号…

【面试笔记】嵌入式软件工程师,汽车电子软件相关

文章目录 1. C语言基础1.1 const1.2 static1.3 回调函数的用法1.4 宏定义1.5 编译、链接过程1.6 堆与栈的区别&#xff1f;1.7 简单的字符串算法题&#xff0c;C语言实现1.7.1 给定一个字符串&#xff0c;按顺序筛选出不重复的字符组成字符串&#xff0c;输出该字符串1.7.2 给定…

数据库(24)——外键约束

概念 外键用来让两张表的数据之间建立连接&#xff0c;从而保证数据的一致性和完整性。 具有外键的表称为子表&#xff0c;关联的表称为父表。 语法 添加外键 CREATE TABLE 表名( 字段名 数据类型, .. [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主…

优化家庭网络,路由器无线中继配置全攻略(中兴E1600无线中继设置/如何解决没有预埋有线网络接口的问题/使用闲置路由实现WIFI扩展)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 网络优化 📒📒 操作步骤 📒💡适用场景🚨 常见问题及解决方案⚓️ 相关链接 ⚓️📖 介绍 📖 在现代家庭生活中,WiFi已经渗透到我们生活的每一个角落,成为了日常生活中不可或缺的一部分。然而,不少用户常常遇到W…

Word忘记保存?请使用Word隐藏备份文件

大家用Word写材料时&#xff0c;如果忘记保存&#xff0c;可以使用Word隐藏备份文件找回未保存的文件。&#xff08;仅供参考&#xff09; Windows7、8、10、11系统的设置如下&#xff1a; 执行上述操作&#xff0c;可以在word文件菜单中信息项的自动保存中找到了。上述内容…

Python | mkvirtualenv命令改变虚拟环境存储位置

文章目录 1、问题引入2、解决方式 1、问题引入 使用mkvirtualenv 命令创建虚拟环境时&#xff0c;默认创建位置在C:\Users你的计算机名目录下&#xff0c;采用下面的方式可以修改虚拟环境存储位置&#xff0c;默认创建位置是Python内置写好的&#xff0c;默认是这样的。 2、解…

企业微信hook接口协议,ipad协议http,chatid转群id

chatid转群id 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信 请求示例 {"uuid":"3240fde0-45e2-48c0-90e8-cb098d0ebe43","chatid":"wrO9o4EAAAeR_nSlmjeX1RWrKAKxN8jQ" } 返回示例 {&…

3072. 将元素分配到两个数组中 II Rust 线段树 + 离散化

题目 给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 现定义函数 greaterCount &#xff0c;使得 greaterCount(arr, val) 返回数组 arr 中 严格大于 val 的元素数量。 你需要使用 n 次操作&#xff0c;将 nums 的所有元素分配到两个数组 arr1 和 arr2 中。在第一次操…

docker 存储 网络 命令

文章目录 1 docker存储1.1 目录挂载2.1卷映射2.1.1卷映射和目录挂载的区别2.1.2卷映射的使用 2 docker网络2.1查看docker的默认网络2.2查看容器的IP2.3容器互通2.4自定义网络2.4.1 创建自定义网络2.4.2创建容器的时候加入到自定义的网络2.4.3使用域名进行容器之间的访问2.4.4re…

LeetCode-92. 反转链表 II【链表】

LeetCode-92. 反转链表 II【链表】 题目描述&#xff1a;解题思路一&#xff1a;简单的翻转链表操作背诵版&#xff1a;解题思路三&#xff1a;0 题目描述&#xff1a; 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 …

[Linux] 软链接使用绝对路径的重要性

文章目录 软链接使用绝对路径的重要性软链接路径复制软链接查看文件类型 软链接使用绝对路径的重要性 软链接路径 软链接必须指定绝对路径&#xff0c;否则复制软链接后&#xff0c;由于软链接的相对路径是从软链接所处位置开始解析的&#xff0c;因此使用相对路径的软链接可…

一次 K8s 故障诊断:从 CPU 高负载到存储挂载泄露根源揭示

一、背景 现代软件部署中&#xff0c;容器技术已成为不可或缺的一环&#xff0c;在云计算和微服务架构中发挥着核心作用。随着容器化应用的普及&#xff0c;确保容器环境的可靠性成为了一个至关重要的任务。这就是容器SRE&#xff08;Site Reliability Engineering&#xff0c…

2024首发!会声会影2024旗舰版,专业编辑新体验!

会声会影2024最新旗舰版是一款专业的视频编辑软件&#xff0c;它集成了多种高级功能&#xff0c;为用户带来极致的视频编辑体验。在这篇文章中&#xff0c;我们将详细介绍该软件的功能和特色&#xff0c;帮助用户更好地了解和使用它。 会声会影全版本绿色安装包获取链接&#…

HarmonyOS鸿蒙-DevEco Studio工具

一、官网下载DevEco Studio工具地址 文章内容: 1、下载工具 2、运行项目 3、安装启动器 https://developer.harmonyos.com/cn/develop/deveco-studio/https://developer.harmonyos.com/cn/develop/deveco-studio/ 下载不同平台工具目录 : 二、 安装DevEco Studio工具 安装的配置…

分布式架构与分布式理论

文章目录 分布式架构什么是分布式系统分布式系统特性分布式系统面临的问题 分布式理论数据一致性CAP理论BASE理论 分布式架构 什么是分布式系统 分布式系统是一个硬件或软件组件分布在不同的网络计算机上&#xff0c;彼此之间仅仅通过消息传递进行通信和协调的系统。 所谓分…

html+CSS+js部分基础运用15

1、完成输入框内容的实时反向输出。 2、银行账户余额变动自动通知项目。 设计要求&#xff1a;单击按钮后&#xff0c;余额按照输入框的数额减少&#xff0c;同时将按钮式的提示信息&#xff08;金额&#xff09;同步改变。利用侦听属性实现余额发生变化时发出提示信息&#x…

LabVIEW减压阀和温控阀综合测试系统

在使用LabVIEW开发阀门测试软件时&#xff0c;特别是针对减压阀和温控阀&#xff0c;测试内容和注意事项包括以下方面&#xff1a; 测试内容 压力测试&#xff1a; 入口压力&#xff1a;测量阀门在不同入口压力下的表现。 出口压力&#xff1a;确保减压阀能够将出口压力控制在…