【动态规划】两个数组问题

文章目录

  • 动态规划(两个数组问题)
    • 1. 最长公共子序列
    • 2. 不相交的线
    • 3. 不同的子序列
    • 4. 交错字符串
    • 5. 两个字符串的最小ASCII和
    • 6. 最长重复子数组
    • 7. 通配符匹配

动态规划(两个数组问题)

1. 最长公共子序列

题目链接

  1. 状态表示

    dp[i][j] 表示 s1 0 到 i 区间内,以及时s2 0 到 j 区间内所有的子序列中,最长的公共子序列

  2. 状态转移方程

    根据最后一个位置的请款分类讨论。

    z5uwarw27c-1692105710163.png

  3. 初始化

    关于字符串的dp问题,空串是有研究意义的。引入空串的概念之后会方便我们的初始化

    这里还可以使用之前的方法,使用辅助节点的方式

  4. 填表顺序

    从下往上,从左到右

  5. 返回值

AC代码:

class Solution 
{
public:
    int longestCommonSubsequence(string text1, string text2) 
    {
        int n = text1.size();
        int m = text2.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 (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[n][m];
    }
};

2. 不相交的线

题目链接

题目分析:根据这个题目可以看到不就是找最长公共子序列嘛

  1. 状态表示

    dp[i][j] 表示 0 到 i 的所有子序列以及 0 到 j 的所有子序列当中,最长的公共子序列

  2. 状态转移方程

    z5uwarw27c-1692105710163.png

  3. 初始化

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) 
    {
        int n = nums1.size();
        int 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. 状态表示

    dp[i][j] 表示 0 到 j 之间的所有子序列中有多少个出现 目标中0 到 i 之间的字母

  2. 状态转移方程

    wwbqeo8ik2-1692159834158.png

  3. 初始化

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    int numDistinct(string s, string t) 
    {
        int n = s.size();
        int m = t.size();
        vector<vector<double>> dp(m + 1, vector<double>(n + 1));
        for (int i = 0; i <= n; i++) dp[0][i] = 1;
        for (int i = 1; i <= m; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                dp[i][j] += dp[i][j - 1];
                if (s[j - 1] == t[i - 1]) dp[i][j] += dp[i - 1][j - 1];
            }
        }
        return dp[m][n];
    }
};

4. 交错字符串

题目链接

  1. 状态表示

    dp[i][j] 表示 s1中[1, i]之间的字符串,以及s2当中[1,j]之间的字符串能否拼接成s3当中[1, i + j]之间的字符串

  2. 状态转移方程

    6bav0zoena-1692234012162.png

  3. 初始化

    当两个字符串都是空的时候,返回的一定是true,当s1 不为空, s2 为空,只要s1有一个不等于s3则直接返回false否则为true

    s2的初始化也一样

  4. 填表

    从上到下,从左到右

  5. 返回值

AC代码:

class Solution 
{
public:
    bool isInterleave(string s1, string s2, string s3) 
    {
        int m = s1.size();
        int n = s2.size();
        if (m + n != s3.size()) return false;
        s1 = " " + s1;
        s2 = " " + s2;
        s3 = " " + s3;
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1));
        dp[0][0] = true;
        for (int i = 1; i <= n; i++) 
        {
            if (s2[i] == s3[i]) dp[0][i] = true;
            else break;
        }
        for (int i = 1; i <= m; i++) 
        {
            if (s1[i] == s3[i]) dp[i][0] = true;
            else break;
        }
        for (int i = 1; i <= m; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                if ((s1[i] == s3[i + j] && dp[i - 1][j]) || (s2[j] == s3[i + j] && dp[i][j - 1]))
                    dp[i][j] = true;
            }
        }
        return dp[m][n];
    }
};

5. 两个字符串的最小ASCII和

题目链接

  1. 状态表示

    分析,这个题目要找两个字符串最小的,可以找到公共最大的然后反向求

    dp[i][j] 表示 [0, i] 以及[0, j]的所有子序列当中,ASCII最大的公共子序列的和

  2. 状态转移方程

    vd6lhlh6jm-1692235583156.png

  3. 初始化

    无需初始化

  4. 填表

    从左到右,从上到下

  5. 返回值

    两个字符串的和前去最大的乘以2

AC代码:

class Solution 
{
public:
    int minimumDeleteSum(string s1, string s2) 
    {
        int m = s1.size();
        int n = s2.size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for (int i = 1; i <= m; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
                if (s1[i - 1] == s2[j - 1])
                {
                    dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + s1[i - 1]);
                }
            }
        }
        int sum = 0;
        for (auto e : s1) sum += e;
        for (auto e : s2) sum += e;
        return sum - dp[m][n] - dp[m][n];
    }
};

6. 最长重复子数组

题目链接

  1. 状态表示

    dp[i][j]以 i 位置为结尾的所有子数组,以及以j 位置为结尾的所有子数组当中,最长公共子数组的长度

  2. 状态转移方程

    1n7eel8afo-1692236963060.png

  3. 初始化

    无需初初始化

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) 
    {
        int m = nums1.size();
        int n = nums2.size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        int ret = 0;
        for (int i = 1; i <= m; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                if (nums1[i - 1] == nums2[j - 1]) 
                {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }
                ret = max(ret, dp[i][j]);
            }
        }
        return ret;
    }
};

7. 通配符匹配

题目链接

  1. 状态表示

    dp[i][j] 表示 p[0, j]区间内子串能否匹配s[0, i]区间内的子串

  2. 状态转移方程

    le1zm27ois-1692322359180.png

    这种有很多表示方法的状态转移方程,需要优化不可能把每个状态都表示出来

    第一种就是采用数学方法来优化:

    image-20230818093607316

    还可以根据状态表示以及实际情况优化状态转移方程

    ok3jt4o0a6-1692322740156.png

  3. 初始化

    p[0][j] == ”*“ 时就一直是true

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    bool isMatch(string s, string p) 
    {
        int m = s.size();
        int n = p.size();
        s = " " + s, p = " " + p;
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1));
        dp[0][0] = true;
        for (int j = 1; j <= n; j++)
        {
            if (p[j] == '*') dp[0][j] = true;
            else break;
        }
        for (int i = 1; i <= m; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                if (p[j] == '*') 
                    dp[i][j] = dp[i- 1][j] || dp[i][j - 1];
                else if (p[j] == '?') dp[i][j] = dp[i - 1][j - 1];
                else 
                {
                    if (s[i] == p[j]) dp[i][j] = dp[i - 1][j - 1];
                }
            }
        }
        return dp[m][n];
    }
};
   {
            if (p[j] == '*') 
                dp[i][j] = dp[i- 1][j] || dp[i][j - 1];
            else if (p[j] == '?') dp[i][j] = dp[i - 1][j - 1];
            else 
            {
                if (s[i] == p[j]) dp[i][j] = dp[i - 1][j - 1];
            }
        }
    }
    return dp[m][n];
}

};


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

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

相关文章

8个免费的在线思维导图制作工具推荐,节省时间提高效率!

思维导图&#xff0c;也称为心智图或思维图&#xff0c;最初由英国的心理学家Tony Buzan提出。它是一种图形化的思维工具&#xff0c;旨在帮助我们组织信息、理解知识和激发创新思维。思维导图最大特点是其中心放射式的结构。一张思维导图通常由一个中心主题发散出各个子主题&a…

WebRTC | 网络传输协议RTP与RTCP

目录 一、UDP与TCP 1. TCP 2. UDP 二、RTP 1. RTP协议头 &#xff08;1&#xff09;V&#xff08;Version&#xff09;字段 &#xff08;2&#xff09;P&#xff08;Padding&#xff09;字段 &#xff08;3&#xff09;X&#xff08;eXtension&#xff09;字段 &#x…

jenkins使用

安装插件 maven publish over ssh publish over ssh 会将打包后的jar包&#xff0c;通过ssh推送到指定的服务器上&#xff0c;&#xff0c;在jenkins中设置&#xff0c;推送后脚本&#xff0c;实现自动部署jar包&#xff0c;&#xff0c; 装了这个插件之后&#xff0c;可以在项…

adb对安卓app进行抓包(ip连接设备)

adb对安卓app进行抓包&#xff08;ip连接设备&#xff09; 一&#xff0c;首先将安卓设备的开发者模式打开&#xff0c;提示允许adb调试 二&#xff0c;自己的笔记本要和安卓设备在同一个网段下&#xff08;同连一个WiFi就可以了&#xff09; 三&#xff0c;在笔记本上根据i…

【MT32F006】MT32F006之定时器延时

本文最后修改时间&#xff1a;2023年03月30日 一、本节简介 本文介绍如何使用MT32F006的定时器做us、ms级的延时。 二、实验平台 库版本&#xff1a;V1.0.0 编译软件&#xff1a;MDK5.37 硬件平台&#xff1a;MT32F006开发板&#xff08;主芯片MT32F006&#xff09; 仿真器…

Docker+Jmeter+InfluxDB+Grafana 搭建性能监控平台

当今互联网发展迅速&#xff0c;应用程序的性能监控显得越来越重要。 DockerJmeterInfluxDBGrafana 是一种常用的性能监控平台&#xff0c;可以帮助开发者快速搭建一套可靠的监控体系。在本文中&#xff0c;我们将介绍如何使用这些工具搭建性能监控平台&#xff0c;以便开发人…

初试rabbitmq

rabbitmq的七种模式 Hello word 客户端引入依赖 <!--rabbitmq 依赖客户端--><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.8.0</version></dependency> 生产者 imp…

DyLoRA:使用动态无搜索低秩适应的预训练模型的参数有效微调

又一个针对LoRA的改进方法&#xff1a; DyLoRA: Parameter-Efficient Tuning of Pretrained Models using Dynamic Search-Free Low Rank Adaptation https://arxiv.org/pdf/2210.07558v2.pdf https://github.com/huawei-noah/KD-NLP/tree/main/DyLoRA Part1前言 LoRA存在…

[oneAPI] 使用序列到序列网络和注意力进行翻译

[oneAPI] 使用序列到序列网络和注意力进行翻译 oneAPI特殊写法使用序列到序列网络和注意力进行翻译Intel Optimization for PyTorch导入包加载数据并对数据进行处理序列到序列网络和注意力模型与介绍编码器解码器简单解码器注意力解码器 训练过程准备训练数据训练模型可视化注意…

隧道广播平面波扬声器的应用

隧道广播平面波扬声器是一款高清晰定向扬声器&#xff0c;采用稀土永磁磁性材料与声波相控阵技术&#xff0c;有效的解决了声音定向问题。是远距离定向声波发射装置是一种革命性的技术&#xff0c;它具有大功、率高清晰、远距离传声特点&#xff0c;可以将声音信息清晰地传输到…

(搜索) 剑指 Offer 12. 矩阵中的路径 ——【Leetcode每日一题】

❓剑指 Offer 12. 矩阵中的路径 难度&#xff1a;中等 给定一个 m * n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构…

代码随想录算法训练营第三十七天 | 738.单调递增的数字,968.监控二叉树

代码随想录算法训练营第三十七天 | 738.单调递增的数字&#xff0c;968.监控二叉树 738.单调递增的数字暴力解法贪心算法:eyes:题目总结:eyes: 968.监控二叉树:eyes:题目总结:eyes: 738.单调递增的数字 题目链接 视频讲解 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y …

微信小程序(原生)搜索功能实现

一、效果图 二、代码 wxml <van-searchvalue"{{ keyword }}"shape"round"background"#000"placeholder"请输入关键词"use-action-slotbind:change"onChange"bind:search"onSearch"bind:clear"onClear&q…

【Linux操作系统】深入探索Linux进程:创建、共享与管理

进程的创建是Linux系统编程中的重要概念之一。在本节中&#xff0c;我们将介绍进程的创建、获取进程ID和父进程ID、进程共享、exec函数族、wait和waitpid等相关内容。 文章目录 1. 进程的创建1.1 函数原型和返回值1.2 函数示例 2. 获取进程ID和父进程ID2.1 函数原型和返回值2.…

java面试基础 -- 普通类 抽象类 接口

目录 抽象类语法 抽象类特性 普通类 & 抽象类 抽象类 & 接口 什么是接口 语法 接口方法 变量 接口特性 抽象类&接口的区别 抽象类语法 在Java中&#xff0c;一个类如果被 abstract 修饰称为抽象类&#xff0c;抽象类中被 abstract 修饰的方法称为抽象…

ZooKeeper的应用场景(分布式锁、分布式队列)

7 分布式锁 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源&#xff0c;那么访问这些资源的时候&#xff0c;往往需要通过一些互斥手段来防止彼此之间的干扰&#xff0c;以保证一致性&#xff0c;…

【Unity每日一记】计时器——各种方法的实现

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

(7)(7.3) 自动任务中的相机控制

文章目录 前言 7.3.1 概述 7.3.2 自动任务类型 7.3.3 创建合成图像 前言 本文介绍 ArduPilot 的相机和云台命令&#xff0c;并说明如何在 Mission Planner 中使用这些命令来定义相机勘测任务。这些说明假定已经连接并配置了相机触发器和云台(camera trigger and gimbal hav…

7.原 型

7.1原型 【例如】 另外- this指向&#xff1a; 构造函数和原型对象中的this都指向实例化的对象 7.2 constructor属性 每个原型对象里面都有个constructor属性( constructor构造函数) 作用&#xff1a;该属性指向该原型对象的构造函数 使用场景: 如果有多个对象的方法&#…

侯捷 八部曲 C++面向对象高级开发(上)+(下)【C++学习笔记】 超详细 万字笔记总结 笔记合集

文章目录 Ⅰ C part1 面向对象编程1 头文件与类的声明1.1 c vs cpp关于数据和函数1.2 头文件与类1.2.1 头文件1.2.2 class的声明1.2.3 模板初识 2 构造函数2.1 inline 函数2.2 访问级别2.3 ctor 构造函数2.3.1 ctor 的写法2.3.2 ctor/函数 重载2.3.3 ctor 放在 private 区 2.4 …