leetCode 583.两个字符串的删除操作 动态规划 + 优化空间复杂度(二维dp、一维dp)

583. 两个字符串的删除操作 - 力扣(LeetCode)

给定两个单词 word1 和 word2 ,返回使得 word1 和  word2 相同所需的最小步数

每步 可以删除任意一个字符串中的一个字符。

示例 1:

输入: word1 = "sea", word2 = "eat"
输出: 2
解释: 第一步将 "sea" 变为 "ea" ,第二步将 "eat "变为 "ea"

示例  2:

输入:word1 = "leetcode", word2 = "etco"
输出:4

 一、递归搜索 + 保存计算结果 = 记忆化搜索

  • 二维memo数组 存储计算过的子问题的结果 
class Solution {
public:// 递归搜索 + 保存计算结果 = 记忆化搜索// 二维memo数组 存储过的子问题的结果int minDistance(string s, string t) {int m = s.size(),n = t.size(),memo[m][n]; // 二维memo数组 存储计算过的子问题的结果;memset(memo,-1,sizeof(memo));// -1 表示没有访问过function<int(int,int)> dfs = [&](int i,int j) -> int {if(i<0) //base case 当i指针越界,此时return j+1;if(j<0) //base casereturn i+1;if (memo[i][j] != -1) // memo中有当前遇到的子问题的解,直接拿来返回return memo[i][j];if (s[i] == t[j]) {  memo[i][j] = dfs(i-1, j-1);} else {// memo[i][j] = min(min(dfs(i-1, j)+1,dfs(i, j-1)+1),dfs(i-1, j-1)+2);// memo[i][j] = min(dfs(i-1, j)+1,dfs(i, j-1)+1);memo[i][j] = min(dfs(i-1, j),dfs(i, j-1))+1;}return memo[i][j];};return dfs(m-1,n-1);}
}

二、动态规划 与 递归 的区别 

  • 递归公式 
if (s[i] == t[j]) {  memo[i][j] = dfs(i-1, j-1);
} else {// memo[i][j] = min(min(dfs(i-1, j)+1,dfs(i, j-1)+1),dfs(i-1, j-1)+2);// memo[i][j] = min(dfs(i-1, j)+1,dfs(i, j-1)+1);memo[i][j] = min(dfs(i-1, j),dfs(i, j-1))+1;
}

递归是自上而下调用,子问题自下而上被解决,最后解决了整个问题,而dp是从base case 出发,通过在dp数组记录中间结果,自下而上地顺序地解决子问题

  • dp解法

1.确定dp数组(dp table)以及下标的含义

dp[i][j]:以i-1为结尾的字符串word1,和以j-1为结尾的字符串word2,想要达到相等,所需要删除元素的最少次数

2.确定递推公式

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);
}

3.dp数组初始化

从递推式可看出,dp[i][0] dp[0][j] 是一定要初始化的

  • dp[i][0]:word2为字符串,以 i-1 为结尾的字符串 word1 需要删除 个元素才能变成空串,和word2相同
  • dp[0][j]:word1为字符串,以 j-1 为结尾的字符串 word2 需要删除 个元素才能变成空串,和word1相同
  • dp[0][0]=0,因为两个空字符串相同,删除操作为0
for(int i=1;i<=m;++i) dp[i][0] = i;
for(int j=1;j<=n;++j) dp[0][j] = j;

4.确定遍历顺序

从递推公式 dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1; dp[i][j] = dp[i - 1][j - 1]可以看出dp[i][j]都是根据正上方、正左方推出来的,所以遍历的时候一定是从上到下,从左到右,这样保证dp[i][j]可以根据之前计算出来的数值进行计算。

5.举例推导dp数组

 (1)动态规划 二维dp

class Solution {
public:int minDistance(string word1, string word2) {int m = word1.size(),n = word2.size();vector<vector<int>> dp(m+1,vector<int>(n+1));for(int i=1;i<=m;++i) dp[i][0] = i;for(int j=1;j<=n;++j) dp[0][j] = j;for(int i=1;i<=m;++i) {for(int j=1;j<=n;++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]+2);else dp[i][j] = min(dp[i-1][j]+1,dp[i][j-1]+1);}}return dp[m][n];}
};
  • 时间复杂度: O(m * n)
  • 空间复杂度: O(m * n)

(2)动态规划 二维dp 优化空间 

class Solution {
public:  // 动态规划 二维dp 优化空间int minDistance(string word1, string word2) {int m = word1.size(),n = word2.size();// vector<vector<int>> dp(m+1,vector<int>(n+1));vector<vector<int>> dp(2,vector<int>(n+1));for(int j=1;j<=n;++j) dp[0][j] = j;for(int i=1;i<=m;++i) {dp[i%2][0] = i;for(int j=1;j<=n;++j) {if(word1[i-1] == word2[j-1]) dp[i % 2][j] = dp[(i-1)%2][j-1];else dp[i%2][j] = min(dp[(i-1)%2][j]+1,dp[i%2][j-1]+1);}}return dp[m%2][n];}
};
  • 时间复杂度: O(m * n)
  • 空间复杂度: O(n)

(3)动态规划 一维dp(滚动数组) 优化空间

class Solution {
public:  // 动态规划 一维dp(滚动数组) 优化空间int minDistance(string word1, string word2) {int m = word1.size(),n = word2.size();vector<int> dp(n+1);for(int j=1;j<=n;++j) dp[j] = j;for(int i=1;i<=m;++i) {// pre 代表dp[i-1][0]int pre = dp[0];// 初始化当前层的 dp[i][0]dp[0] = i;for(int j=1;j<=n;++j) {int tmp = dp[j];if(word1[i-1] == word2[j-1]) dp[j] = pre;else dp[j] = min(dp[j]+1,dp[j-1]+1);pre = tmp;}}return dp[n];}
};
  • 时间复杂度: O(m * n)
  • 空间复杂度: O(n)

本题除了这种解法外,还有这种解题思路:先求出最长公共子序列,然后 word1.size() + word2.size() - 两倍的最长公共子序列

求最长公共子序列,可以看我往期的这篇文章:leetCode 1143.最长公共子序列

(1)二维dp 

class Solution {
public: int minDistance(string word1, string word2) {int m = word1.size(),n = word2.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) {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],dp[i][j-1]);}}return m + n - 2 * dp[m][n];}
};
  • 时间复杂度: O(m * n)
  • 空间复杂度: O(m * n)

(2)二维dp:优化空间 

class Solution {
public:  // 方法二 二维dp 优化空间int minDistance(string word1, string word2) {int m = word1.size(),n = word2.size();vector<vector<int>> dp(2,vector<int>(n+1)); for(int i=1;i<=m;++i) {for(int j=1;j<=n;++j) {if(word1[i-1] == word2[j-1]) dp[i%2][j] = dp[(i-1)%2][j-1] + 1;else dp[i%2][j] = max(dp[(i-1)%2][j],dp[i%2][j-1]);}}return m + n - 2 * dp[m%2][n];}
};
  • 时间复杂度: O(m * n)
  • 空间复杂度: O(n)

(3)一维dp:优化空间

class Solution {
public:// 方法二 一维dp 优化空间int minDistance(string word1, string word2) {int m = word1.size(),n = word2.size();vector<int> dp(n+1); for(int i=1;i<=m;++i) {int pre = dp[0];for(int j=1;j<=n;++j) {int tmp = dp[j];if(word1[i-1] == word2[j-1]) dp[j] = pre + 1;else dp[j] = max(dp[j],dp[j-1]);pre = tmp;}}return m + n - 2 * dp[n];}
};
  • 时间复杂度: O(m * n)
  • 空间复杂度: O(n)

参考和推荐文章、视频:

代码随想录 (programmercarl.com)

动态规划之子序列,还是为了编辑距离做铺垫 | LeetCode:583.两个字符串的删除操作_哔哩哔哩_bilibili

来自代码随想录课堂的截图:

 

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

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

相关文章

基于springboot实现校园闲置物品交易平台系统项目【项目源码+论文说明】

基于springboot实现校园闲置物品交易平台系统演示 摘要 社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的交易方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。互联网具有便利性&#xff0c;速度快&#xff0c;效率高&am…

nodejs+vue+elementui酒店客房服务系统mysql带商家

视图层其实质就是vue页面&#xff0c;通过编写vue页面从而展示在浏览器中&#xff0c;编写完成的vue页面要能够和控制器类进行交互&#xff0c;从而使得用户在点击网页进行操作时能够正常。 简单的说 Node.js 就是运行在服务端的 JavaScript。 前端技术&#xff1a;nodejsvueel…

基于单目相机的2D测量(工件尺寸和物体尺寸)

目录 1.简介 2.基于单目相机的2D测量 2.1 想法&#xff1a; 2.2 代码思路 2.2 主函数部分 1.简介 基于单目相机的2D测量技术在许多领域中具有重要的背景和意义。 工业制造&#xff1a;在工业制造过程中&#xff0c;精确测量是确保产品质量和一致性的关键。基于单目相机的2…

Go语言入门心法(二): 结构体

Go语言入门心法(一) Go语言入门心法(二): 结构体 一: Go语言中结构体认知 go语言中的结构体认知升维:go语言中的结构体本身是一种自定义的数据类型,即然是数据类型,则可以用来声明其他的变量,被声明的变量即为结构体的实例对象go语言中的结构体融合了c语言中的结构体体征和面…

Xshell7和Xftp7超详细下载教程(包括安装及连接服务器附安装包)

1.下载 1.官网地址&#xff1a; XSHELL - NetSarang Website 选择学校免费版下载 2.将XSHELL和XFTP全都下载下来 2.安装 安装过程就是选择默认选项&#xff0c;然后无脑下一步 3.连接服务器 1.打开Xshell7&#xff0c;然后新建会话 2.填写相关信息 出现Connection establi…

JVM 性能调优参数

JVM分为堆内存和非堆内存 堆的内存分配用-Xms和-Xmx -Xms分配堆最小内存&#xff0c;默认为物理内存的1/64&#xff1b; -Xmx分配最大内存&#xff0c;默认为物理内存的1/4。 非堆内存分配用-XX:PermSize和-XX:MaxPermSize -XX:PermSize分配非堆最小内存&#xff0c;默认为物理…

【LeetCode高频SQL50题-基础版】打卡第5天:第26~30题

文章目录 【LeetCode高频SQL50题-基础版】打卡第5天&#xff1a;第26~30题⛅前言超过5名学生的课&#x1f512;题目&#x1f511;题解 求关注者的数量&#x1f512;题目&#x1f511;题解 只出现一次的最大数字&#x1f512;题目&#x1f511;题解 买下所有产品的客户&#x1f…

《进化优化》第4章 遗传算法的数学模型

文章目录 4.1 图式理论4.2 马尔可夫链4.3 进化算法的马尔可夫模型的符号4.4 遗传算法的马尔可夫模型4.4.1 选择4.4.2 变异4.4.3 交叉 4.5 遗传算法的动态系统模型4.5.1 选择4.5.2 变异4.5.3 交叉 4.1 图式理论 图式是描述一组个体的位模式&#xff0c;其中用*来表示不在乎的位…

如何在Ubuntu 20.04.6 LTS系统上运行Playwright自动化测试

写在前面 这里以 Ubuntu 20.04.6 LTS为例。示例代码&#xff1a;自动化测试代码。 如果过程中遇到其他非文本中提到的错误&#xff0c;可以使用搜索引擎搜索错误&#xff0c;找出解决方案&#xff0c;再逐步往下进行。 一、 环境准备 1.1 安装python3 1.1.1 使用APT安装Py…

python+opencv+深度学习实现二维码识别 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; pythonopencv深度学习实现二维码识别 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;3分 该项目较为新颖&…

跨语言深入探讨如何实现方法增强:Java Go的多策略实现

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

虚拟现实VR技术在医疗行业的应用介绍

虚拟现实 (VR) 虽然经常与游戏联系在一起&#xff0c;但不可否认&#xff0c;未来科技少不了虚拟现实&#xff0c;其应用可以彻底改变许多行业。在医疗领域&#xff0c;无数人正在探索 VR 可以帮助患者和医疗从业者实现更好的治疗结果治疗方式&#xff0c;比如在手术、疼痛管理…

最新水果FL Studio21.2中文汉化版本覆盖升级

FLStudio中文21最新版本以其使用速度而闻名&#xff0c;是一个高度复杂的音乐制作环境。FL Studio免费&#xff0c;联合国音序器音频和MIDI每个复合编辑都是音乐。现代的DAW是一种非凡的野兽。首先&#xff0c;它在很大程度上把自己放在了(几乎)每个人记录过程的核心。其次&…

【计算机网络】——前言计算机网络发展的历程概述

主页点击直达&#xff1a;个人主页 我的小仓库&#xff1a;代码仓库 C语言偷着笑&#xff1a;C语言专栏 数据结构挨打小记&#xff1a;初阶数据结构专栏 Linux被操作记&#xff1a;Linux专栏 LeetCode刷题掉发记&#xff1a;LeetCode刷题 算法&#xff1a;算法专栏 C头…

【2023全网最全教程】web自动化测试入门

一、自动化测试基本介绍 1 自动化测试概述&#xff1a; 什么是自动化测试&#xff1f;一般说来所有能替代人工测试的方式都属于自动化测试&#xff0c;即通过工具和脚本来模拟人执行用例的过程。 2 自动化测试的作用 减少软件测试时间与成本改进软件质量通过扩大测试覆盖率…

hive 之select 中文乱码

此处的中文乱码和mysql的库表 编码 latin utf 无关。 直接上案例。 有时候我们需要自定义一列&#xff0c;有时是汉字有时是字母&#xff0c;结果遇到这种情况了。 说实话看到这真是糟心。这谁受得了。 单独select 没有任何问题。 这是怎么回事呢&#xff1f; 经过一番检查&…

【C++】-c++11的知识点(中)--lambda表达式,可变模板参数以及包装类(bind绑定)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

十六、【橡皮擦工具组】

文章目录 橡皮擦背景橡皮擦1. 一次取样2. 连续取样3. 取样背景色板 魔术橡皮擦 橡皮擦 橡皮擦跟我们平常生活中所用的橡皮擦是一样&#xff0c;它是将图层的内容擦除,只剩下空白部分。另外当我们按住Alt的键去擦除空白部分的时候&#xff0c;也可以将背景的部分显示出来。 另…

深入解析Spring Cloud Gateway的GlobalFilter

文章目录 摘要引言GlobalFilter的作用使用GlobalFilter默认的GlobalFilter自定义GlobalFilter 示例代码配置GlobalFilter配置文件方式代码方式 高级用法&#xff1a;重写GlobalFilter思路代码实现 结论参考文献 摘要 本文将详细介绍Spring Cloud Gateway中的GlobalFilter&…

VR会议:远程带看功能,专为沉浸式云洽谈而生

随着科技的不断发展&#xff0c;VR技术已经成为当今市场上较为热门的新型技术之一了&#xff0c;而VR会议远程带看功能&#xff0c;更是为用户提供更加真实、自然的沉浸式体验。 随着5G技术的发展&#xff0c;传统的图文、视频这种展示形式已经无法满足消费者对信息真实性的需求…