day57 判断子序列 不同的子序列 两个字符串的删除操作 编辑距离

news2024/11/19 16:30:08

题目1  392 判读子序列

题目链接  392 判断子序列

题意

判断字符串s是否为字符串t的子序列  (子序列的相对位置在原字符串中不改变)

就是求最长公共子序列的长度与字符串s的长度是否相等

动态规划

1)确定dp数组及下标i的含义

dp[i][j] 表示以s[i-1]结尾的字符串与以t[j-1]结尾的字符串公共序列的最大长度

2)dp数组初始化

根据递推公式 dp[0][1] = 0   dp[1][0] = 0

3)递推公式

if(s[i-1] == t[j-1]) dp[i][j] = dp[i-1][j-1] +1;

else dp[i][j] = dp[i-1][j];  考虑1种情况  删除t字符串中该位置的元素(减1),该位置元素对应不等

4)遍历顺序

根据递推公式 从前向后遍历 从左向右遍历

for(int i =1; i <= s.size(); i++){

     for(int j = 1; j <= t.size(); j++){

     }

}

5)打印dp数组

代码

class Solution {
public:
    bool isSubsequence(string s, string t) {
        if(s.size() > t.size()) return false;
        int result = 0;
        //定义dp数组  初始化
        vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
        for(int i  = 1; i <= s.size(); i++){
            for(int j = 1; j <= t.size(); j++){
                if(s[i-1] == t[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
                else dp[i][j] = dp[i][j-1];
                result = max(result, dp[i][j]);
            }
        }
        if(result == s.size()) return true;
    return false;
    }
};
  • 时间复杂度:O(n × m)
  • 空间复杂度:O(n × m)

题目2 115 不同的子序列

题目链接 115 不同的子序列

题意

统计字符串s的子序列中字符串t出现的次数  即字符串s里面删除t能否变成字符串t

动态规划

1)确定dp数组及下标i的含义

dp[i][j]   以s[i-1]为结尾的字符串s中有t[j-1]为结尾的字符串t的个数

2)dp数组初始化

根据递推公式  dp[i][0]=1   字符串s中有1个空字符串

dp[0][i] = 0  空字符串s中有0个字符串t

dp[0][0]  空字符串s中有1个空字符串t

3)递推公式

若两个元素相等,那么就不考虑这个位置的元素  个数取决于:

1)前面已有的个数  dp[i-1][j-1]    2)字符串s中相邻两元素相同,模拟删除第一个(减1)  dp[i-1][j]

if(s[i-1] == t[i-1])   dp[i][j] = dp[i-1][j-1] + dp[i-1][j]

若不等,则模拟将元素从字符串s删除掉(减1)

else dp[i][j] = dp[i-1][j]     

4)遍历顺序

根据递推公式  从左向右遍历,从上到下遍历

for(int i = 1; i <= s.size(); i++){

   for(int j = 1; j <= t.size(); j++){

   }

}

5)打印dp数组

本题要求判断个数,所以要使用dp[s.size()][t.size()]求解最终的个数

如果再定义result与dp[i][j]比较了,会遇到这样的情况  s="eee"   t="eee"会得到错误的结果3

因为这里面的每个e都相同,在中间过程会重复计数,所以会产生错误

所以还是应该使用dp[s.size()][t.size()]表示以s.size()-1结尾的字符串s中有t.size()-1结尾的字符串t的个数,说明字符串s遍历到了末尾的位置,求解的是全部的个数

代码

class Solution {
public:
    int numDistinct(string s, string t) {
        if(s.size() < t.size()) return 0;
        //定义并初始化dp数组
        vector<vector<uint64_t>> dp(s.size() + 1, vector<uint64_t>(t.size() + 1, 0));
        //初始化dp数组
        for(int i = 0; i <= s.size(); i++){
            dp[i][0] = 1;
        }
        for(int i = 1; i <= s.size(); i++){
            for(int j = 1; j <= t.size(); j++){
                if(s[i-1] == t[j-1]){
                    dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
                }else {
                    dp[i][j] = dp[i-1][j];
                }
                // cout << "i=" << i << " " << "j=" << j << " " << dp[i][j] << endl; 
            }
        }
        return dp[s.size()][t.size()];
    }
};
  • 时间复杂度: O(n * m)
  • 空间复杂度: O(n * m)

题目3  583 两个字符串的删除操作

题目链接 583 两个字符串的删除操作

题意

返回使得单词word1和word2相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。

动态规划

1)确定dp数组及下标i的含义

dp[i][j]  以word1[i-1]结尾的word1和以word2[j-1]结尾的word2相同的最小操作次数

2)dp数组初始化

根据递推公式 dp[0][j] = j        dp[i][0] = i

其它下标对应的dp[i][j]可初始化为任意值

3)递推公式

两个字符相同时,操作次数不受影响取决于前面的情况

if(word[i-1] == word2[j-1]) dp[i][j] = dp[i-1][j-1];

两个字符不相同时,那么就要删除一个字符(操作次数+1)  或是 删除两个字符(操作次数+2)

else dp[i][j] = min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+2)

4)遍历顺序

根据递推公式,从前向后遍历,从左向右遍历

for(int i = 1; i <= word1.size(); i++){

        for(int j = 1; j < word2.size(); j++){

        }

}

5)打印dp数组

代码

class Solution {
public:
    int minDistance(string word1, string word2) {
        //定义dp数组
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 2, 0));
        for(int i = 0; i <= word1.size(); i++){
            dp[i][0] = i;
        }
        for(int j = 0; j <= word2.size(); j++){
            dp[0][j] = j;
        }
        for(int i = 1; i <= word1.size(); i++){
            for(int j = 1; j <= word2.size(); j++){
                if(word1[i-1] == word2[j-1]) dp[i][j] = dp[i-1][j-1];
                else dp[i][j] = min(dp[i-1][j-1] + 2, min(dp[i-1][j] + 1, dp[i][j-1] + 1));  
            }
        }
        return dp[word1.size()][word2.size()];
    }
};
  • 时间复杂度: O(n * m)
  • 空间复杂度: O(n * m)
法2:使用最长公共子序列进行求解

word1.size() + word2.size() - 2 * coseqlen;

动态规划

1)确定dp数组及下标i的含义

dp[i][j]  以word1[i-1]结尾的word1和以word2[j-1]结尾的word2最长公共子序列的长度

2)dp数组初始化

根据递推公式 dp[0][j] = 0       dp[i][0] = 0

其它下标对应的dp[i][j]可初始化为任意值

3)递推公式

两个字符相同时,操作次数不受影响取决于前面的情况

if(word[i-1] == word2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;

两个字符不相同时,那么就要删除一个字符(操作次数+1)  或是 删除两个字符(操作次数+2)

else dp[i][j] = max(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])

4)遍历顺序

根据递推公式,从前向后遍历,从左向右遍历

for(int i = 1; i <= word1.size(); i++){

        for(int j = 1; j < word2.size(); j++){

        }

}

代码

class Solution {
public:
    int minDistance(string word1, string word2) {
        //定义dp数组
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));
        for(int i = 0; i <= word1.size(); i++){
            dp[i][0] = 0;
        }
        for(int j = 0; j <= word2.size(); j++){
            dp[0][j] = 0;
        }
        for(int i = 1; i <= word1.size(); i++){
            for(int j = 1; j <= word2.size(); j++){
                if(word1[i-1] == word2[j-1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }else{
                    dp[i][j] = max(dp[i-1][j-1], max(dp[i-1][j], dp[i][j-1]));
                }
            }
        }
        return word1.size() + word2.size() - 2 * dp[word1.size()][word2.size()];
    }
};
  • 时间复杂度: O(n * m)
  • 空间复杂度: O(n * m)

题目4  72 编辑距离

题目链接 72 编辑距离

题意

返回将word1转换为word2的最小次数(可以插入\删除\替换一个字符)

添加元素和删除元素是一个等价的操作(在word1中添加元素等价于在word2中删除元素)而替换操作是一个新的动作,需要另外考虑

动态规划

1)确定dp数组及下标i的含义

dp[i][j] 以word1[i-1]结尾的word1和以word2[j-1]结尾的word2相同的最小操作次数

2)dp数组初始化

根据递推公式 dp[i][0] = i   dp[0][j] = j  其他下标对应的dp[i][j]可以初始化为任意值。

3)递推公式

if(word1[i-1] == word2[j-1])  dp[i][j] = dp[i-1][j-1];

else dp[i][j] = min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+1);

注意本题多了一个操作就是替换的操作  而添加操作与删除操作是等价的

4)遍历顺序

根据递推公式 从上到下遍历,从左往右遍历

for(int i = 1; i <= word1.size(); i++){

        for(int j = 1; j <= word2.size(); j++){

        }

]

5)打印dp数组

代码

class Solution {
public:
    int minDistance(string word1, string word2) {
        //定义dp数组
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));
        //dp数组初始化
        for(int i = 0; i <= word1.size(); i++){
            dp[i][0] = i;
        }
        for(int j = 0; j <= word2.size(); j++){
            dp[0][j] = j;
        }
        for(int i = 1; i <= word1.size(); i++){
            for(int j = 1; j <= word2.size(); j++){
                if(word1[i-1] ==  word2[j-1]) dp[i][j] = dp[i-1][j-1];
                else dp[i][j] = min(dp[i-1][j-1] + 1, min(dp[i-1][j] + 1, dp[i][j-1] + 1));
            }
        }
        return dp[word1.size()][word2.size()];
    }
};
  • 时间复杂度: O(n * m)
  • 空间复杂度: O(n * m)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频知识整理

1 视频播放器原理 视频播放器播放一个互联网上的视频文件&#xff0c;需要经过以下几个步骤&#xff1a; 解协议&#xff1a;将流媒体协议的数据&#xff0c;解析为标准的相应的封装格式数据 解封装&#xff1a;将封装格式的数据&#xff0c;分离成为音频流压缩编码数据和视…

【ESP32使用MAX98357播放音频】

【ESP32使用MAX98357播放音频】 1. 前言2. 先决条件2.1 硬件准备2.2 软件准备2.3 接线3. 核心代码3.1 驱动实现3.2 代码解析4. 播放音乐5. 结论1. 前言 在物联网和智能家居领域,音频播放功能越来越受到重视。ESP32作为一款功能强大的微控制器,结合MAX98357音频放大器模块,可…

Java入门教程||Java 变量

Java 变量 Java教程 - Java变量 变量由标识符&#xff0c;类型和可选的初始化程序定义。变量还具有范围&#xff08;可见性/生存期&#xff09;。 Java变量类型 在Java中&#xff0c;必须先声明所有变量&#xff0c;然后才能使用它们。变量声明的基本形式如下所示&#xff1…

CVPR 2024 | 仅需文本或图像提示,新框架CustomNeRF精准编辑3D场景

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 美图影像研究院&#xff08;MT Lab&#xff09;与中国科学院信息工程研究所、北京航空航天大…

AutoGen - Build Powerful AI Agents with ChatGPT/GPT-4

原文:AutoGen - Build Powerful AI Agents with ChatGPT/GPT-4 | MLExpert - Crush Your Machine Learning interview In this tutorial, well explore AutoGen1, a Microsoft library that lets you create LLM applications with agents. These agents can communicate and …

Qt控件---输入类

文章目录 QLineEdit&#xff08;单行输入&#xff09;设置验证器 QTextEdit&#xff08;多行输入&#xff09;QComboBox&#xff08;下拉框&#xff09;通过读取文件设置条目 QSpinBox & QDoubleSpinBox&#xff08;数字微调框&#xff09;QDateEdit & QTimeEdit &…

十款组装台式电脑可能会用到的主板,看下有没有适合你的

序言 组装台式电脑,还是升级老化的电脑?以下是你需要了解的有关选择合适主板的所有信息。 如果说内存、显卡和 CPU 是 PC 充满活力的四肢,是完成工作和启动你喜爱的游戏的部件,那么主板就是骨架和结缔组织,甚至是灵魂。 可以肯定的是,其他组件在决定 PC 的整体性能和功…

golang 使用栈模拟计算器

思路&#xff1a; // Author sunwenbo // 2024/4/12 16:51 package mainimport ("errors""fmt""strconv" )// 使用数组来模拟一个栈的应用 type Stack struct {MaxTop int //表示栈最大可以存放数的个数Top int //表示栈底&#xff…

【Java集合进阶】数据结构(二又树,二又查找树,平衡二又树)

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

java项目实战之图书管理系统(1)

✅作者简介&#xff1a;大家好&#xff0c;我是再无B&#xff5e;U&#xff5e;G&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 1.背景 图书管理系统是一种用于管理图书…

MongoDB 初识

介绍 MongoDB是一种开源的文档型数据库管理系统&#xff0c;它使用类似于JSON的BSON格式&#xff08;Binary JSON&#xff09;来存储数据。与传统关系型数据库不同&#xff0c;MongoDB不使用表和行的结构&#xff0c;而是采用集合&#xff08;Collection&#xff09;(Mysql表)和…

Linux 快问快答

如果对于找 Java 后端开发的话&#xff0c;我感觉会这几个差不多了&#xff0c;面试官应该不会问的这么详细吧。一般就问问 Linux 的几个常用的命令&#xff0c;然后做一些简单的性能排查就好了。如果面试被问到另外的问题&#xff0c;那我再补充进来&#xff0c;现在先掌握这么…

979: 输出利用先序遍历创建的二叉树的后序遍历序列

解法&#xff1a; #include<iostream> using namespace std; struct TreeNode {char val;TreeNode* left;TreeNode* right;TreeNode(char c) :val(c), left(NULL), right(NULL) {}; }; TreeNode* buildTree() {char c;cin >> c;if (c #) {return NULL;}TreeNode*…

CTF之comment

网站的登录框里有提示 账号&#xff1a;zhangwei 密码&#xff1a;zhangwei***&#xff08;后三位要自己猜&#xff09; 用burpsuit抓包爆破发现密码为zhangwei666 进去后就一个留言榜&#xff08;目前没发现怎么用&#xff09; 扫一下网站发现git泄露 1.下载 进入root用户&…

964: 数细胞

样例&#xff1a; 解法&#xff1a; 1.遍历矩阵 2.判断矩阵[i][j]&#xff0c;若是未标记细胞则遍历相邻所有未标记细胞并标记&#xff0c;且计数 实现&#xff1a;遍历相邻所有未标记细胞 以DFS实现&#xff1a; function dfs(当前状态) {if (终止条件) {}vis[标记当前状…

构建动态交互式H5导航栏:滑动高亮、吸顶和锚点导航技巧详解

功能描述 产品要求在h5页面实现集锚点、吸顶及滑动高亮为一体的功能&#xff0c;如下图展示的一样。当页面滑动时&#xff0c;内容区域对应的选项卡高亮。当点击选项卡时&#xff0c;内容区域自动滑动到选项卡正下方。 布局设计 css 布局 为了更清晰的描述各功能实现的方式&…

CentOS 7安装Nginx

说明&#xff1a;本文介绍如何在CentOS 7操作系统中安装Nginx 下载安装 首先&#xff0c;去官网上下载Nginx压缩包&#xff0c;官网地址&#xff1a;https://nginx.org/en/download.html&#xff0c;我这里下载稳定版1.24.0&#xff1b; 上传到云服务器上&#xff0c;解压&am…

数据分析案例(三):基于RFM分析的客户分群

实验2 基于RFM分析的客户分群 Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢…

读书笔记:高效能人士的七个习惯

前言 恐惧感和不安全感 现代社会&#xff0c;太多的人饱受恐惧感的折磨。他们恐惧将来&#xff0c;恐惧失业&#xff0c;恐惧无力养家。这种弱点&#xff0c;常常助长了一种倾向&#xff1a;无论在工作时&#xff0c;还是回到家中&#xff0c;都倾向于零风险的生活&#xff0…

CMMI认证是什么?如何确定CMMI认证的目标和范围

CMMI&#xff08;Capability Maturity Model Integration&#xff09;认证是一种用于评估和改进组织软件和项目管理过程的框架。它由美国国防部软件工程所&#xff08;SEI&#xff09;开发&#xff0c;旨在帮助组织提高其软件和项目管理的成熟度水平。 CMMI认证的意义在于&…