2021 后端笔试准备 10(动态规划:编辑距离)

编辑距离

编辑距离定义:

编辑距离,也叫莱文斯坦距离(Levenshtein Distance),是针对二个字符串(例如英文字)的差异程度的量化量测,量测方式是看至少需要多少次的处理才能将一个字符串变成另一个字符串。

题目 input: str1 = "abc"      str2 = "yabd"

题目描述:

给出两个字符串,求出最小的编辑距离,从str1 转换到 str2。每个字符总共有三个转换操作:插入,删除,替换。

如图所示,题目给出的例子的结果是2,如果需要将str1 转换乘 str2, 我们可以看到,我们需要在字符串 abc 面前插入一个字符 y,同时需要将字符串abc的c替换成字符d。这总共是执行了两步操作。所以结果2。


解决思路:

1. 画二维图(转换成python就是一个二维数组)

画一个二维图去计算每一个字符需要转换乘对应字符所需要的距离是多少,注意:每个字符串前面都会有一个空字符。中间的空白空格需要填写的是,从str1中的一个子字符串 转换到 str2的一个子字符串最小的编辑。


2. 填写编辑距离

说明: 图中的位置我会用坐标来表示(0,0),(1,0)代表坐标的意思,黑色数字代表编辑距离

首先我们先从 行 开始,

第二行的空字符串准换到,第二列的空字符串是相等的,所以我们既不用 插入操作,也不用删除操作,也不用替换操作,就能转换到另一个。所以编辑距离是0。

再从这个空字符串转换到 “ ” y 我们需要几步呢? 在空字符串添加里面加上一个“ ” y 我们就转化成了“ ” y,我们执行了一个 添加 的操作,所以编辑距离是1。

如果我们需要从空字符串转换到 “ ” y a 我们需要几步呢?在字符串 “ ” y 的基础上再加一个 a 我们就得到了  " " y a, 所以我们又执行了一个 添加 操作,所以编辑距离在上一个添加的操作的基础上增加了一个 1,总共是2,后面的以此类推。

然后我们开始看 列

第三行的 ” “ a 转换到 ” “ 我们需要执行什么操作?删除!,我们需要移除 a ,所以我们执行一次移除的操作,因此编辑距离 + 1,0 + 1 = 1,所以编辑距离是1。下面的以此类推,” “ a b 转换到 ” “ 我们需要执行两次移除操作,所以总共是 2 。。。


我们继续填写

我们看到坐标(1,-1)最小的编辑距离是1,” “ a 转换到 ” “ y 我们只需要将 a 替换成 y。但是我们也可以先移除 (0,-1)a 坐标, 然后增加(1,0)一个 y,这样的编辑距离是2。但是我们需要填入的是最小编辑距离,所以最终我们填入1。

然后我们移动到坐标(2,-1)我们可以看到这里的编辑距离是1,” “ a 转换到 ” “ y a 我们需要添加一个 y。如图中绿色字的部分,因为a 和 a是相同的,所以我们消除它,然后我们可以发现字符串只剩下了 str1 = “ ”,str2 = " " y,所以str1 到 str2 只需要 添加 y。所以编辑距离是1。


(3, -1)的编辑距离我们可以理解成:“ ” a 在转成 “ ” y a 的基础上插入了一个 字符b,所以可以看成是在 “ ” a 转成 “ ” y a的基础上加一个1,所以我们可以看出“ ” a转成 “ ” y a b 的编辑距离是 1 + 1 = 2。后面的d也可以这样理解,在 “ ” y a b 的基础上再新增一个 1,所以(4, -1) 的编辑距离是3。

因此我们发现这个编辑距离填写的规律,如下图所示坐标(3,-1)的编辑距离是它 上方,左上方,左边的最小数 + 1(在两个字符不一样的情况下。坐标(4, -1) 同理 min(上方,左上方,左边)= min(4, 3, 2)  =  2, 因此(4, -1)的编辑距离等于 2 + 1 = 3。但是在两个字符串一样的情况,如(2, -1),a 和 a是相同的所以不需要 +1,所以(2,-1)处的编辑距离 = min(2,1,1)= 1。接下来的方框大家都会填了吧?


最后是最终的二维表的所有编辑距离,我们最终的答案是取最右下角的数字,也就是2,所以我们最终的答案是2。


最后补充一点,左上角的编辑距离总是三个数中最小的

时间复杂度分析:

O(nm) time,因为你要建立的是一个str1+1行 和 str2+1列的二维数组,并且填写里面每一个元素,并返回最后一个元素,所以程序的时间复杂度是和程序输入str1和str2长度有关

空间复杂度分析:

我们需要开辟一个str1+1行 和 str2+1列的二维数组取存储我们的编辑距离,所以我们的空间复杂度也是O(nm),当然还有优化的空间。

3. 代码

接下来我们进入代码环节

这次代码同样也分成了,有注释和和没有注释的版本,没有注释的请拉到最底部

第六行代码生成list中的第一行是

[0,1,2,3,4,....] 因为空字符转换乘其他非空字符串就是一直加加加

列也同样是0,1,2,3,4.... 列和行的长度和输入的str1 str2的长度有关


没有注释的版本



恭喜你看到了这里!

接下来我们就来看看如何降低空间复杂度!

我们真的需要把整个n * m的list的空间开辟出来吗?我们最终使用的空间其实是蓝色方框中的部分,我们实际算距离的部分只需要绿色方框和红色方框。所以当我们最终输入的列越短,我们所需要的空间越少。因此我们在处理输入的时候我们可以将比较短的string输入作为我们的列,比较长的则作为我们的行。

所以我们最终的空间复杂度可以是O(min(n, m))


代码:有注释+无注释


无注释


Reference:代码来自Algoexpert,以学习作为主要目的来分享的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容