LeetCode--72

news/发布时间2024/5/15 11:07:55

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 由小写英文字母组成

...害,直接看答案了。

class Solution {
public:int minDistance(string word1, string word2) {int n=word1.length();int m=word2.length();if(n*m==0)return n+m;vector<vector<int>>D(n+1,vector<int>(m+1));for(int i=0;i<n+1;i++){D[i][0]=i;}for(int j=0;j<m+1;j++){D[0][j]=j;}for(int i=1;i<n+1;i++){for(int j=1;j<m+1;j++){int left=D[i-1][j]+1;int down=D[i][j-1]+1;int left_down=D[i-1][j-1];if(word1[i-1]!=word2[j-1])left_down+=1;D[i][j]=min(left,min(down,left_down));}}return D[n][m];}
};

本来我是不服的,但是看到评论区我就释怀了。

真几把悲哀。

想法
编辑距离算法被数据科学家广泛应用,是用作机器翻译和语音识别评价标准的基本算法。

最直观的方法是暴力检查所有可能的编辑方法,取最短的一个。所有可能的编辑方法达到指数级,但我们不需要进行这么多计算,因为我们只需要找到距离最短的序列而不是所有可能的序列。

方法一:动态规划
思路和算法

我们可以对任意一个单词进行三种操作:

插入一个字符;

删除一个字符;

替换一个字符。

题目给定了两个单词,设为 A 和 B,这样我们就能够六种操作方法。

但我们可以发现,如果我们有单词 A 和单词 B:

对单词 A 删除一个字符和对单词 B 插入一个字符是等价的。例如当单词 A 为 doge,单词 B 为 dog 时,我们既可以删除单词 A 的最后一个字符 e,得到相同的 dog,也可以在单词 B 末尾添加一个字符 e,得到相同的 doge;

同理,对单词 B 删除一个字符和对单词 A 插入一个字符也是等价的;

对单词 A 替换一个字符和对单词 B 替换一个字符是等价的。例如当单词 A 为 bat,单词 B 为 cat 时,我们修改单词 A 的第一个字母 b -> c,和修改单词 B 的第一个字母 c -> b 是等价的。

这样以来,本质不同的操作实际上只有三种:

在单词 A 中插入一个字符;

在单词 B 中插入一个字符;

修改单词 A 的一个字符。

这样以来,我们就可以把原问题转化为规模较小的子问题。我们用 A = horse,B = ros 作为例子,来看一看是如何把这个问题转化为规模较小的若干子问题的。

在单词 A 中插入一个字符:如果我们知道 horse 到 ro 的编辑距离为 a,那么显然 horse 到 ros 的编辑距离不会超过 a + 1。这是因为我们可以在 a 次操作后将 horse 和 ro 变为相同的字符串,只需要额外的 1 次操作,在单词 A 的末尾添加字符 s,就能在 a + 1 次操作后将 horse 和 ro 变为相同的字符串;

在单词 B 中插入一个字符:如果我们知道 hors 到 ros 的编辑距离为 b,那么显然 horse 到 ros 的编辑距离不会超过 b + 1,原因同上;

修改单词 A 的一个字符:如果我们知道 hors 到 ro 的编辑距离为 c,那么显然 horse 到 ros 的编辑距离不会超过 c + 1,原因同上。

那么从 horse 变成 ros 的编辑距离应该为 min(a + 1, b + 1, c + 1)。

注意:为什么我们总是在单词 A 和 B 的末尾插入或者修改字符,能不能在其它的地方进行操作呢?答案是可以的,但是我们知道,操作的顺序是不影响最终的结果的。例如对于单词 cat,我们希望在 c 和 a 之间添加字符 d 并且将字符 t 修改为字符 b,那么这两个操作无论为什么顺序,都会得到最终的结果 cdab。

你可能觉得 horse 到 ro 这个问题也很难解决。但是没关系,我们可以继续用上面的方法拆分这个问题,对于这个问题拆分出来的所有子问题,我们也可以继续拆分,直到:

字符串 A 为空,如从 转换到 ro,显然编辑距离为字符串 B 的长度,这里是 2;

字符串 B 为空,如从 horse 转换到 ,显然编辑距离为字符串 A 的长度,这里是 5。

因此,我们就可以使用动态规划来解决这个问题了。我们用 D[i][j] 表示 A 的前 i 个字母和 B 的前 j 个字母之间的编辑距离。

如上所述,当我们获得 D[i][j-1],D[i-1][j] 和 D[i-1][j-1] 的值之后就可以计算出 D[i][j]。

D[i][j-1] 为 A 的前 i 个字符和 B 的前 j - 1 个字符编辑距离的子问题。即对于 B 的第 j 个字符,我们在 A 的末尾添加了一个相同的字符,那么 D[i][j] 最小可以为 D[i][j-1] + 1;

D[i-1][j] 为 A 的前 i - 1 个字符和 B 的前 j 个字符编辑距离的子问题。即对于 A 的第 i 个字符,我们在 B 的末尾添加了一个相同的字符,那么 D[i][j] 最小可以为 D[i-1][j] + 1;

D[i-1][j-1] 为 A 前 i - 1 个字符和 B 的前 j - 1 个字符编辑距离的子问题。即对于 B 的第 j 个字符,我们修改 A 的第 i 个字符使它们相同,那么 D[i][j] 最小可以为 D[i-1][j-1] + 1。特别地,如果 A 的第 i 个字符和 B 的第 j 个字符原本就相同,那么我们实际上不需要进行修改操作。在这种情况下,D[i][j] 最小可以为 D[i-1][j-1]。

那么我们可以写出如下的状态转移方程:

若 A 和 B 的最后一个字母相同:

D[i][j]=min⁡(D[i][j−1]+1,D[i−1][j]+1,D[i−1][j−1])=1+min⁡(D[i][j−1],D[i−1][j],D[i−1][j−1]−1)\begin{aligned} D[i][j] &= \min(D[i][j - 1] + 1, D[i - 1][j]+1, D[i - 1][j - 1])\\ &= 1 + \min(D[i][j - 1], D[i - 1][j], D[i - 1][j - 1] - 1) \end{aligned}
D[i][j]

  
=min(D[i][j−1]+1,D[i−1][j]+1,D[i−1][j−1])
=1+min(D[i][j−1],D[i−1][j],D[i−1][j−1]−1)

 
若 A 和 B 的最后一个字母不同:

D[i][j]=1+min⁡(D[i][j−1],D[i−1][j],D[i−1][j−1])D[i][j] = 1 + \min(D[i][j - 1], D[i - 1][j], D[i - 1][j - 1])
D[i][j]=1+min(D[i][j−1],D[i−1][j],D[i−1][j−1])
所以每一步结果都将基于上一步的计算结果,示意如下:

对于边界情况,一个空串和一个非空串的编辑距离为 D[i][0] = i 和 D[0][j] = j,D[i][0] 相当于对 word1 执行 i 次删除操作,D[0][j] 相当于对 word1执行 j 次插入操作。

综上我们得到了算法的全部流程。

 

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

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

相关文章

html5盒子模型

1.边框的常用属性 border-color 属性 说明 示例 border-top-color 上边框颜色 border-top-color:#369; border-right-color 右边框颜色 border-right-color:#369; border-bottom-color 下边框颜色 border-bottom-color:#fae45b; border-left-color 左边框颜色…

Python学习 --- 面向对象

1.什么是对象 1.Python中创建类的关键字是 class 2.类的成员方法 1.函数是写在类外面的,方法则是写在类里面的 1.上面这一段代码中就展示了如何在方法中访问类的成员变量: self.成员变量名 3.魔术方法 魔术方法其实就是python中的类中的内置方法,下面这几个只是我们比较常…

多输入时序预测|GWO-CNN-LSTM|灰狼算法优化的卷积-长短期神经网络时序预测(Matlab)

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 灰狼优化算法&#xff1a; 卷积神经网络-长短期记忆网络&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容…

清华系2B模型杀出支持离线本地化部署,可以个人电脑或者手机上部署的多模态大模型,超越 Mistral-7B、LLaMA-13B

清华系2B模型杀出支持离线本地化部署&#xff0c;可以个人电脑或者手机上部署的多模态大模型&#xff0c;超越 Mistral-7B、LLaMA-13B。 2 月 1 日&#xff0c;面壁智能与清华大学自然语言处理实验室共同开源了系列端侧语言大模型 MiniCPM&#xff0c;主体语言模型 MiniCPM-2B …

Vue前端对请假模块——请假开始时间和请假结束时间的校验处理

开发背景&#xff1a;Vueelement组件开发 业务需求&#xff1a;用户提交请假申请单&#xff0c;请假申请的业务逻辑处理 实现&#xff1a;用户选择开始时间需要大于本地时间&#xff0c;不得大于请假结束时间&#xff0c;请假时长根据每日工作时间实现累加计算 页面布局 在前…

iOS App 上架指南及关键

引言 上架App Store是将iOS应用提交申请并上线的过程&#xff0c;旨在让应用在App Store上展示&#xff0c;吸引用户并获取流量。本文将介绍iOS上架的整体流程&#xff0c;并提供一些建议和注意事项。 一、iOS上架的整体流程 1. 申请开发者账号 首先&#xff0c;需要申请苹…

ElementUI组件的安装和使用

Element UI 是一款基于 Vue 2.0 的桌面端组件库&#xff0c;主要用于快速构建网站的前端部分。它提供了丰富的组件&#xff0c;如按钮、输入框、表格、标签页等&#xff0c;以及一些布局元素&#xff0c;如布局容器、分割线等。Element UI 的设计风格简洁&#xff0c;易于上手&…

文心一言 VS 讯飞星火 VS chatgpt (203)-- 算法导论15.3 2题

二、对一个16个元素的数组&#xff0c;画出2.3.1节中MERGE-SORT过程运行的递归调用树。解释备忘技术为什么对MERGE-SORT这种分治算法无效。需要写代码的时候&#xff0c;请用go语言。 文心一言&#xff0c;代码不完整&#xff1a; 首先&#xff0c;让我们明确2.3.1节中的MERG…

计算机毕业设计 基于SpringBoot的宠物商城网站系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【element+vue】点击加号增加一行,点击减号删除一行

代码实现&#xff1a; 页面部分&#xff1a; vueelement 备注&#xff1a;v-if “i>0” &#xff08;保证第一行不出现减号&#xff09; <div v-for"(item,i) in studentList"><el-form-item label"学生:" prop"name"><el-i…

机器学习:朴素贝叶斯算法(Python)

一、朴素贝叶斯算法的实现 naive_bayes_classifier.py import numpy as np import collections as cc # 集合的计数功能 from scipy.stats import norm # 极大似然估计样本的均值和标准方差 from data_bin_wrapper import DataBinsWrapperclass NaiveBayesClassifier:"…

线程的状态图

线程创建之后&#xff0c;调用start()方法开始运行。当线程执行wait()方法之后&#xff0c;线程进入等待状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态&#xff0c;而超时等待状态相当于在等待状态的基础上增加了超时限制&#xff0c;也就是超时时间到达…

Redis集群搭建笔记

redis集群: 1.hash取余算法 2.一致性hash算法 3.哈希槽算法 以下使用哈希槽算法 Redis 3主3从搭建 新建6个Redis Docker容器实例 docker run -d --name redis-node-1 --net host --privilegedtrue -v /usr/local/develop/redis/share/redis-node-1:/data redis:6.0.8 --c…

C# 通过共享内存调用C++ 算法

需求&#xff1a; C#程序调用 C开发的dll. 一种C# 程序调用c 算法方案_算法怎么被c#调用-CSDN博客 上回书说到&#xff0c;将c算法封装为dll 插件&#xff0c;c加载后&#xff0c;暴露C风格接口&#xff0c;然后供C#调用。但是这样有几个问题&#xff1a; 1&#xff0c;一是…

解析ChatGPT Plus相比chatgpt3.5有哪些优势

「ChatGPT Plus」提供更出色的对话体验和更广泛的应用能力&#xff0c;学生可以用来写作、职场人也可以用来写计划书、策划书等等&#xff0c;并且问它一些问题比搜索引擎好用多了简直。但普通人使用起来有一点门槛&#xff0c;并且升级4.0也难住了许多爱好者。 ChatGPT主要功能…

设计模式——策略模式

定义: 该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把便用算法的责任和算法的实现分割开来,并委派给不算法进象行管理。 主要角色如下: 示例: 假定现在需要实现一个…

Mybatis Plus 打印 SQL 语句(包含执行耗时)

文章目录 一、前言二、引入依赖三、添加配置3.1 第一步&#xff1a;修改 application.yml 配置文件3.2 第二步&#xff1a;添加 p6spy 配置文件 四、看看打印效果五、注意点 一、前言 我们先配置一下 Mybatis Plus 打印 SQL 功能&#xff08;包括执行耗时&#xff09;&#xf…

Python分支和循环结构及其应用(文末送书)

一、分支结构 应用场景 我们写的Python代码都是一条一条语句顺序执行&#xff0c;这种代码结构通常称之为顺序结构。然而仅有顺序结构并不能解决所有的问题。 if语句的使用 在Python中&#xff0c;要构造分支结构可以使用if、elif和else关键字。所谓关键字就是有特殊含义的…

【前端素材】推荐优质后台管理系统Uena平台模板(附源码)

一、需求分析 后台管理系统&#xff08;或称作管理后台、管理系统、后台管理平台&#xff09;是一种专门用于管理网站、应用程序或系统后台运营的软件系统。它通常由一系列功能模块组成&#xff0c;为管理员提供了管理、监控和控制网站或应用程序的各个方面的工具和界面。以下…

《现代职业教育》是什么级别的刊物?是正规期刊吗?能评职称吗?

​问题解答&#xff1a; 问&#xff1a;《现代职业教育》是什么级别的刊物&#xff1f; 答&#xff1a;省级 问&#xff1a;《现代职业教育》杂志版面费多少&#xff1f; 答&#xff1a;可以私信 问&#xff1a;《现代职业教育》是核心期刊吗&#xff1f; 答&#xff1a;…
推荐文章