力扣第72题 编辑距离 (增 删 改) C++ 动态规划 附Java代码

题目

72. 编辑距离

中等

相关标签

字符串   动态规划

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数  。

你可以对一个单词进行如下三种操作:

  • 插入一个字符
  • 删除一个字符
  • 替换一个字符

示例 1:

输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')

示例 2:

输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

提示:

  • 0 <= word1.length, word2.length <= 500
  • word1 和 word2 由小写英文字母组成

思路和解题方法

具体来说,对于给定的两个字符串 word1word2,首先创建一个二维数组 dp 来保存它们之间的编辑距离。然后,分别初始化数组的第一行和第一列,使得 dp[i][0] = idp[0][j] = j,其中 ij 分别表示字符串 word1word2 的长度。这样初始化是为了表示将 word1 和空串(或者将 word2 和空串)进行匹配时的编辑距离。

接下来,从第二行和第二列开始,对于每个位置 (i,j),先判断 word1word2 在当前位置上的字符是否相同。如果相同,则说明不需要进行任何编辑操作,因此 dp[i][j] 可以直接继承上一个位置的编辑距离,即 dp[i-1][j-1]。否则,需要在上一个位置的编辑距离的基础上增加一些编辑操作,例如插入、删除或替换字符等。这时,可以考虑三种情况,并选择其中编辑距离最小的一种:

  1. word1 的第 i 个位置插入一个字符,使得 word1word2 的前 j 个字符相同,此时编辑距离为 dp[i][j-1] + 1

  2. word1 的第 i 个位置删除一个字符,使得 word1 的前 i-1 个字符和 word2 的前 j 个字符相同,此时编辑距离为 dp[i-1][j] + 1

  3. word1 的第 i 个位置替换一个字符,使得 word1word2 的前 i 个字符和 j 个字符分别相同,此时编辑距离为 dp[i-1][j-1] + 1

因此,对于每个位置 (i,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-1][j], dp[i][j-1]}) + 1;

其中,min({dp[i-1][j-1], dp[i-1][j], dp[i][j-1]}) 表示选取上述三种编辑操作中编辑距离最小的一种,加上一次操作所需的编辑距离 1,即可得到当前位置 (i,j) 的最小编辑距离。

最后,返回 dp[w1][w2],即两个字符串的完全匹配所需的最小编辑距离。

复杂度

        时间复杂度:

                O(n*n)

        时间复杂度为 O(n*n),其中 n 为两个字符串的长度之和。这是因为算法使用了一个二维数组存储子问题的解,需要计算该数组中所有 n*n 个位置的值。

        空间复杂度

                O(n*n)

        空间复杂度也为 O(n*n),因为需要使用一个二维数组来存储所有子问题的解。

        如果想要将空间复杂度优化到 O(n) 级别,则可以使用滚动数组的技巧,只保留当前行和上一行的值即可,但会使得代码实现稍微有些复杂。

c++ 代码

class Solution {
public:int minDistance(string word1, string word2) {int w1 = word1.size(), w2 = word2.size();// 定义一个二维动态数组 dp,其中 dp[i][j] 表示将 word1 的前 i 个字符转换为 word2 的前 j 个字符所需要的最少操作次数。vector<vector<int>> dp(w1+1, vector<int>(w2+1, 0));// 初始化第一行和第一列,即将一个空字符串转换成另一个字符串所需的最少操作次数。for(int i = 0; i <= w1; i++) dp[i][0] = i;for(int j = 0; j <= w2; j++) dp[0][j] = j;// 从第二行和第二列开始,按照状态转移方程进行计算。for(int i = 1; i <= w1; i++) {for(int j = 1; j <= w2; j++) {// 如果 word1 的第 i 个字符与 word2 的第 j 个字符相等,则不需要进行任何操作。if(word1[i-1] == word2[j-1])dp[i][j] = dp[i-1][j-1];// 如果 word1 的第 i 个字符与 word2 的第 j 个字符不相等,则需要进行以下三种操作中的一种来进行转换操作:// 1. 在 word1 中插入一个字符;// 2. 在 word2 中插入一个字符;// 3. 替换 word1 中的第 i 个字符或者 word2 中的第 j 个字符。elsedp[i][j] = min({dp[i-1][j-1], dp[i-1][j], dp[i][j-1]}) + 1;}}// 返回将 word1 转换成 word2 的最少操作次数。return dp[w1][w2];}
};

Java代码

  1. 首先获取两个字符串的长度,即 word1.length()word2.length(),分别赋值给变量 mn
  2. 接下来,创建一个二维数组 dp,大小为 (m + 1) × (n + 1),用于保存计算过程中的编辑距离。这里多加了一行和一列是为了存储空串与 word1word2 的匹配情况。
  3. 然后,通过两个嵌套的循环遍历数组 dp 中的每个位置 (i, j),其中 i 表示 word1 的前 i 个字符,j 表示 word2 的前 j 个字符。
  4. 对于每个位置 (i, j),首先判断 word1word2 在当前位置上的字符是否相同,即 word1.charAt(i - 1) == word2.charAt(j - 1)。如果相同,则说明不需要进行任何编辑操作,所以将 dp[i][j] 的值设置为 dp[i - 1][j - 1],即继承上一个位置的编辑距离。
  5. 如果不相同,则需要考虑插入、删除和替换字符三种编辑操作中的最小编辑距离。这里使用 Math.min 方法来取得三者中的最小值,并加上一次操作所需的编辑距离 1,即 Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1,然后将结果赋值给 dp[i][j]
  6. 最后,返回 dp[m][n],即两个字符串的完全匹配所需的最小编辑距离。

class Solution {public int minDistance(String word1, String word2) {// 获取两个字符串的长度int m = word1.length();int n = word2.length();// 创建一个二维数组来保存编辑距离int[][] dp = new int[m + 1][n + 1];// 初始化dp数组的第一行和第一列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.charAt(i - 1) == word2.charAt(j - 1)) {// 如果相同,则不需要进行任何编辑操作dp[i][j] = dp[i - 1][j - 1];} else {// 如果不同,则需要进行插入、删除或替换等操作,选取其中编辑距离最小的一种dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;}}}// 返回编辑距离数组的最后一个元素,即两个字符串的完全匹配所需的最小编辑距离return dp[m][n];}
}

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

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

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

相关文章

Python Fastapi+Vue+JWT实现注册、登录、状态续签【登录保持】

文章目录 一、实现流程1.注册2.登录3.登录保持【状态续签】二、实现方法1.注册2.登录+登陆状态保持* 后端部分* 前端部分一、实现流程 1.注册 Created with Raphal 2.3.0

【机器学习范式】监督学习,无监督学习,强化学习, 半监督学习,自监督学习,迁移学习,对比分析+详解与示例代码

目录 1. 监督学习 (Supervised Learning): 2. 无监督学习 (Unsupervised Learning): 3. 强化学习 (Reinforcement Learning): 4. 半监督学习 (Semi-Supervised Learning): 5. 自监督学习 (Self-Supervised Learning): 6. 迁移学习 (Transfer Learning): 7 机器学习范式应…

Git可视化界面的操作,SSH协议的以及IDEA集成Git

目录 一. Git可视化界面的操作 二. gitee的ssh key 2.1 SSH协议 2.2 ssh key 三. IDEA集成Git 3.1 分享项目 3.2 下载项目 一. Git可视化界面的操作 上一篇博客只用到了git的命令窗口&#xff0c;现在就来看看可视化窗口要怎么操作。 点击Git GUI Here GUI界面 在g…

ceph-deploy bclinux aarch64 ceph 14.2.10

ssh-copy-id&#xff0c;部署机免密登录其他三台主机 所有机器硬盘配置参考如下&#xff0c;计划采用vdb作为ceph数据盘 下载ceph-deploy pip install ceph-deploy 免密登录设置主机名 hostnamectl --static set-hostname ceph-0 .. 3 配置hosts 172.17.163.105 ceph-0 172.…

HTML使用lable将文字与控件进行关联以获取焦点

先养养眼再往下看 注释很详细&#xff0c;直接上代码 <form action""><!-- 第一种方法:用id的方式绑定账户(文字)和输入框 --><label for"zhanghu">账户</label><input "text" id"zhanghu" name"ac…

Python环境安装、Pycharm开发工具安装(IDE)

Python下载 Python官网 Python安装 Python安装成功 Pycharm集成开发工具下载&#xff08;IDE&#xff09; PC集成开发工具 Pycharm集成开发工具安装&#xff08;IDE&#xff09; 安装完成 添加环境变量&#xff08;前面勾选了Path不用配置&#xff09; &#xff08;1&…

NO.304 二维区域和检索 - 矩阵不可变

题目 给定一个二维矩阵 matrix&#xff0c;以下类型的多个请求&#xff1a; 计算其子矩形范围内元素的总和&#xff0c;该子矩阵的 左上角 为 (row1, col1) &#xff0c;右下角 为 (row2, col2) 。 实现 NumMatrix 类&#xff1a; NumMatrix(int[][] matrix) 给定整数矩阵 …

Redis数据库的使用

【官网】https://redis.com/ 【中文官网】https://redis.p2hp.com/ 【官方推荐的客户端】https://redis.io/resources/clients/ 1、Qt连接Redis的方式 第三方库c&#xff1a;【hiredis】https://github.com/redis/hiredis第三方库c&#xff1a;【redis-plus-plus】https://gi…

JS实现数据结构与算法

队列 1、普通队列 利用数组push和shif 就可以简单实现 2、利用链表的方式实现队列 class MyQueue {constructor(){this.head nullthis.tail nullthis.length 0}add(value){let node {value}if(this.length 0){this.head nodethis.tail node}else{this.tail.next no…

LLM代码生成器的挑战【GDELT早期观察】

越来越多的研究开始对LLM大模型生成的代码的质量提出质疑&#xff0c;尽管科技行业不断推出越来越多的旨在增强甚至取代人类编码员的工具。 随着我们&#xff08;GDELT&#xff09;继续探索和评估越来越多的此类工具&#xff0c;以下是我们的一些早期观察结果。 在线工具推荐&a…

【ARM Coresight OpenOCD 系列 3 -- OpenOCD 常用命令与扫描链scan_chain】

文章目录 1.1 TAP Declaration1.1.1 扫描链 1.2 Autoprobing1.3 DAP declaration (ARMv6-M, ARMv7 and ARMv8 targets) 1.1 TAP Declaration 测试访问端口&#xff08;TAP&#xff09;是JTAG的核心。TAP扮演许多角色&#xff0c;包括&#xff1a; 调试目标&#xff1a;CPU TA…

linux安装git

目录 声明 前言 正文 &#xff08;1&#xff09;下载git压缩包 &#xff08;2&#xff09;git压缩包解压 &#xff08;3&#xff09;解压完成后需要进行源码的编译操作 a.首先进去到解压后的文件目录中&#xff1a; b.执行&#xff1a; 编译的过程中可能遇到的问题&am…

设计模式案例 (三)

文章目录 系列文章目录前言一、单例模式懒汉模式case 包饿汉模式case 包懒汉模式枷锁case 包 系列文章目录 第一章 设计模式案例 (一) 第二章 设计模式案例 &#xff08;二) 第三章 设计模式案例 &#xff08;二) 文章目录 系列文章目录前言一、单例模式懒汉模式case 包饿汉模…

给OFFICE增加一个功能搜索

OFFICE功能几乎是无限的。不论你怎么熟悉&#xff0c;总有出乎意料的功能。前几天我使用EXCEL时&#xff0c;发现一个功能改名了。于是我就想&#xff0c;OFFICE应该增加一个功能搜索&#xff1a; 提供一个搜索输入栏。这个已经有了。输入搜索字串弹出一个面板&#xff0c;附带…

Spring Boot: 约定优于配置的软件设计思想

文章目录 传统Spring框架的繁琐配置1. **管理jar包依赖**2. **维护web.xml**3. **维护Dispatch-Servlet.xml配置项**4. **应用部署到Web容器**5. **第三方组件集成到Spring IOC容器中的配置项维护** Spring Boot的简化与自动化1. Spring Boot Starter启动依赖2. 自动装配机制3.…

vue和小程序的异同之处

Vue和小程序&#xff08;微信小程序&#xff09;是两种不同的前端开发框架&#xff0c;它们有一些相似之处&#xff0c;但也有一些主要的区别。 相似之处&#xff1a; 都是用于构建前端应用程序的框架。都支持组件化开发&#xff0c;将页面拆分成独立的组件进行开发和复用。都…

【狂神说Java】Dubbo + Zookeeper

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;狂神说Java &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c;永远…

【海德教育】什么是函授教育呢?

函授教育&#xff08;correspondence education &#xff09;是运用通信方式进行的一种远距离教育活动。学员以自学函授教材为主&#xff0c;面授为辅。教学环节包括自学教材&#xff0c;面授辅导&#xff0c;通信答疑&#xff0c;集中实验、实习、讲评作业&#xff0c;阶段测验…

跨域:利用JSONP、WebSocket实现跨域访问

跨域基础知识点&#xff1a;跨域知识点 iframe实现跨域的四种方式&#xff1a;http://t.csdnimg.cn/emgFr 注&#xff1a;本篇中使用到的虚拟主机也是上面iframe中配置的 目录 JSONP跨域 JSONP介绍 跨域实验&#xff1a; WebSocket跨域 websocket介绍 跨域实验 JSONP跨域…

javaSE学习笔记(五)集合框架-Collection,List,Set,Map,HashMap,Hashtable,ConcurrentHashMap

目录 四、集合框架 1.集合概述 集合的作用 集合和数组的区别 集合继承体系 数组和链表 数组集合 链表集合 2.Collection 方法 集合遍历 并发修改异常 3.List List集合的特有功能&#xff08;核心是索引&#xff09; 集合遍历 并发修改异常产生解决方案ListIterato…