代码随想录算法训练营第五十九天|115.不同的子序列、 583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结篇

news2024/11/23 15:00:34

代码随想录算法训练营第五十九天

115.不同的子序列

题目链接:115.不同的子序列

  1. 确定dp数组以及下标的含义:dp[i][j] :以下标i - 1为结尾的s,和以下标j - 1为结尾的t,s中t的个数dp[i][j]
  2. 确定递推公式:
    s[i - 1] == t[j - 1],左边+左上,不考虑当前s、t两个相同字母+s不考虑当前字母t考虑
    不等的话s加不加当前字母个数没区别,就等于s不考虑当前字母的个数
    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];
    }
    
  3. dp数组如何初始化:t是空字符串,任意s都有1个空字符串。s是空,都有0个t。
  4. 确定遍历顺序:从前向后遍历。
  5. 打印dp数组。
    打印dp数组
class Solution {
public:
    int numDistinct(string s, string t) {
        vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
        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];
                }
            }
        }
        return dp[s.size()][t.size()];
    }
};

583. 两个字符串的删除操作

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

  1. 确定dp数组以及下标的含义:dp[i][j] :以下标i - 1为结尾的word1,和以下标j - 1为结尾的word

  2. 2,删除元素次数dp[i][j]

  3. 确定递推公式:
    两个元素相同,不进行删除操作,次数和不加这两个字母相同就是dp[i-1][j-1]
    两个元素不同,删word1当前元素次数+1和删word2当前元素次数+1哪个小取哪个。

    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);
     }
    
  4. dp数组如何初始化:word1是空另外一个要删空的次数就是word2中元素的个数就是j,word2是空,另一个要删空的次数就是word1中元素的个数就是i

  5. 确定遍历顺序:从前向后遍历。

  6. 打印dp数组。

class Solution {
public:
    int minDistance(string word1, string word2) {
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));
        for (int i = 1; i <= word1.size(); i++) {
            dp[i][0] = i;
        }
        for (int j = 1; 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, dp[i][j - 1] + 1);
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

72. 编辑距离

题目链接:72. 编辑距离

  1. 确定dp数组以及下标的含义:dp[i][j] :以下标i - 1为结尾的word1,和以下标j - 1为结尾的word
  2. 2,编辑元素次数dp[i][j]
  3. 确定递推公式:
    两个元素相同,不进行删除操作,次数和不加这两个字母相同就是dp[i-1][j-1]
    两个元素不同,删word1当前元素次数+1和删word2当前元素次数+1哪个小取哪个,替换元素就是不考虑当前的2个元素操作次数+1。
    if (word1[i - 1] == word2[j - 1]) {
    	dp[i][j] = dp[i - 1][j - 1];
     } else {
     	dp[i][j] = min(min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + 1);
     }
    
  4. dp数组如何初始化:word1是空另外一个要删空的次数就是word2中元素的个数就是j,word2是空,另一个要删空的次数就是word1中元素的个数就是i
  5. 确定遍历顺序:从前向后遍历。
  6. 打印dp数组。
class Solution {
public:
    int minDistance(string word1, string word2) {
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));
        for (int i = 1; i <= word1.size(); i++) {
            dp[i][0] = i;
        }
        for (int j = 1; 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(min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + 1);
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

编辑距离总结篇

  1. 两个字符串做匹配,dp数组含义基本为s[i-1]为结尾,t[j-1]为结尾的操作次数或子序列个数…为了方便把dp[i][0]和dp[0][j]空出来方便初始化
  2. 递推公式一般分为s[i-1]==t[j-1]和不等两种情况
  3. 初始化时候要考虑dp[i][0]和dp[0][j],其他的位置取任意值即可,因为都会被递推公式覆盖
  4. 遍历顺序都是从左到右,从上到下。
  5. 有问题时需打印dp数组看和预期是否有差别。

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

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

相关文章

学习记录:VS2019+OpenCV3.4.1实现SURF库函数的调用

最近在学习opencv的使用&#xff0c;在参照书籍《OpenCV3编程入门》实现SURF时遇到不少问题&#xff0c;下面做归纳总结。 错误 LNK2019 无法解析的外部符号 “public: static struct cv::Ptr __cdecl cv::xfeatures2d::SURF::create(double,int,int,bool,bool)” (?createSUR…

Obsidian 工作区Workspace:实现切换和管理工作区的多任务处理插件

工作区 工作区是Obsidian 的核心插件之一&#xff0c;旨在帮助用户更好地管理和组织他们的工作环境。 功能简介 工作区保存和切换&#xff1a;Workspace 插件允许用户保存当前的窗口布局和打开的笔记状态&#xff0c;用户可以随时切换到不同的工作区&#xff0c;这样可以根据…

【星海随笔】云解决方案学习日志篇(二) kafka、Zookeeper、Fielbeat

Elastic 中国社区官方博客 https://blog.csdn.net/ubuntutouch/category_9209092.html Kafka kafka的源代码是基于Scala语言编写的&#xff0c;运行在Java虚拟机&#xff08;即:JVM&#xff09;上。因此&#xff0c;在安装kafka之前需要先安装JDK Kafka 为什么依赖 Zookeepe…

WebSocket 入门教程

什么是 WebSocket&#xff1f; WebSocket 是一种通信协议&#xff0c;它在单个 TCP 连接上提供全双工通信。与传统的 HTTP 不同&#xff0c;WebSocket 允许服务器主动向客户端推送数据&#xff0c;而不仅仅是客户端请求数据。这使得 WebSocket 非常适用于需要低延迟和实时通信…

【星座运势】本周财运分析,巨蟹座财富潜力大开!

大家好&#xff01;今天我们来谈谈巨蟹座本周的财富运势。经过调查和数据分析&#xff0c;我发现巨蟹座这周的财运潜力很大&#xff01;接下来&#xff0c;我将用通俗易懂的语言&#xff0c;通过代码说明&#xff0c;向大家展示巨蟹座的财富运势。 首先&#xff0c;我们需要通…

通俗范畴论2 有向图与准范畴

退一步海阔天空&#xff0c;在正式进入范畴论之前&#xff0c;我们可以重新审视一下我们是如何认识世界的&#xff0c;有了这个对人类认识世界过程的底层理解&#xff0c;可以帮助我们更好地理解范畴论。 对于人类认识世界&#xff0c;最神奇的一点就是这个世界居然是可以认识…

【SpringBoot】SpringBoot:实现文件上传和下载功能

文章目录 引言项目初始化添加依赖 配置文件存储位置实现文件上传功能创建文件上传控制器创建上传页面 实现文件下载功能创建文件下载控制器 安全性和最佳实践文件大小限制文件类型验证文件名和路径验证文件下载时的安全性 测试与部署示例&#xff1a;编写单元测试 部署结论 引言…

C++的异常捕获

目录 C语言的异常处理方式 C的异常处理方式 异常的抛出与捕获 抛出与捕获原则 自定义异常体系 异常安全 异常规范 异常的优缺点 优点 缺点 C语言的异常处理方式 1、终止程序 常见形式&#xff1a;assert 缺陷&#xff1a;太过强硬&#xff0c;如果发生内存错误&#…

文心一言 VS 讯飞星火 VS chatgpt (282)-- 算法导论20.4 3题

三、在 CONNECTED-COMPONENTS 作用于一个有 k 个连通分量的无向图 G(V&#xff0c;E) 的过程中&#xff0c;FIND-SET 需要调用多少次&#xff1f; UNION 需要调用多少次&#xff1f;用 |V| 、 |E| 和 k 来表示你的答案。如果要写代码&#xff0c;请用go语言。 文心一言&#x…

【Java】过滤器/拦截器

文章目录 两者区别request链路全过程 在实际开发中&#xff0c;过滤器和拦截器都是经常使用的技术&#xff0c;但一被提及到其区别时&#xff0c;整个人就愣住了&#xff0c;好像没有认真地对两者进行区别和总结&#xff0c;这两者之间也确实很容易混淆&#xff0c;因此结合了很…

C++ 54 之 继承中同名的静态成员处理

#include <iostream> using namespace std;// 父类 class Base07{ public:static int m_a; // 静态成员&#xff0c;类内定义static void fun(){cout << "Base中的fun"<< endl;}static void fun(int a){cout << "Base中的fun(int a)&qu…

53. QT插件开发--插件(动态库so)的调用与加载

1. 说明 在使用QT进行插件库的开发之后,还需要将这个插件库程序生成的so动态链接库加载到主程序框架中进行使用,才能达到主程序的模块化开发的效果。在前一篇文章插件创建中介绍了如何在QT中开发插件库,并提供外部接口调用。本篇博客的主要作用是模拟在主程序框架中加载动态…

EasyRecovery2024数据恢复神器#电脑必备良品

EasyRecovery数据恢复软件&#xff0c;让你的数据重见天日&#xff01; 大家好&#xff01;今天我要给大家种草一个非常实用的软件——EasyRecovery数据恢复软件&#xff01;你是不是也曾经遇到过不小心删除了重要的文件&#xff0c;或者电脑突然崩溃导致数据丢失的尴尬情况呢&…

element-ui input输入框和多行文字输入框字体不一样

页面中未作样式修改&#xff0c;但是在项目中使用element-ui input输入框和多行文字输入框字体不一样&#xff0c;如下图所示&#xff1a; 这是因为字体不一致引起的&#xff0c;如果想要为Element UI的输入框设置特定的字体&#xff0c;你可以在你的样式表中添加以下CSS代码…

快速UDP网络连接之QUIC协议介绍

文章目录 一、QUIC协议历史1.1 问题&#xff1a;QUIC为什么在应用层实现1.2 QUIC协议相关术语1.3 QUIC和TCP对比1.4 QUIC报文格式1.4.1 QUIC报文格式-Stream帧11.4.2 QUIC报文格式-Stream帧2 二、QUIC的特点2.1 连接建立低时延&#xff0c;2.2 多路复用流复用-HTTP1.1流复用-HT…

SpringBoot整合H2数据库并将其打包成jar包、转换成exe文件二(补充)

SpringBoot整合H2数据库并将其打包成jar包、转换成exe文件二&#xff08;补充&#xff09; 如果你想在cmd命令窗口内看到程序运行&#xff0c;即点开弹出运行窗口&#xff0c;关闭时exe自动关闭。 需要再launch4j上进行如下操作&#xff1a; 这样转换好的exe就可以有控制台了…

springboot + Vue前后端项目(第十六记)

项目实战第十六记 写在前面1 第一个bug1.1 完整的Role.vue 2 第二个bug2.1 修改路由router下面的index.js 总结写在最后 写在前面 发现bug&#xff0c;修复bug 1 第一个bug 分配菜单时未加入父id&#xff0c;导致分配菜单失效 <!-- :check-strictly"true" 默…

人工智能对零售业的影响

机器人、人工智能相关领域 news/events &#xff08;专栏目录&#xff09; 本文目录 一、人工智能如何改变零售格局二、利用人工智能实现购物体验自动化三、利用人工智能改善库存管理四、通过人工智能解决方案增强客户服务五、利用人工智能分析消费者行为六、利用 AI 打造个性化…

C++前期概念(重)

目录 命名空间 命名空间定义 1. 正常的命名空间定义 2. 命名空间可以嵌套 3.头文件中的合并 命名空间使用 命名空间的使用有三种方式&#xff1a; 1:加命名空间名称及作用域限定符&#xff08;::&#xff09; 2:用using将命名空间中某个成员引入 3:使用using namespa…

TCP协议报头详解

目录 前言 TCP特点 TCP报头 1.源端口和目的端口 2.序号 3.确认号 4.数据偏移 5.保留 6.控制位 ① 紧急URG&#xff08;URGent&#xff09; ② 确认ACK&#xff08;ACKnowledgment&#xff09; ③ 推送PSH&#xff08;PuSH&#xff09; ④复位RST&#xff08;ReSeT&…