题目分析

题目链接:https://leetcode.com/problems...
对于长度为x的字符串s1和长度为y的字符串s2,从s1改变成s2最少要经过多少次“增加”、“删除”或“替换”?

为了使用动态规划算法,要先将父问题分解成子问题(父问题和子问题是同一种问题,只不过分解得到的子问题规模更小)。
那么现在就需要我们找出父问题和子问题之间的转移关系。推导父子问题之间的转移关系有2中思路:

  • 要解决父问题,需要先解决哪些子问题

    • 要求解两个字符串之间的最小编辑距离,需要用到哪些更小的字符串之间的编辑距离?
  • 假设已经知道一些子问题的答案,能计算出哪些同一类型、规模更大的父问题

    • 如果已经知道某一对字符串之间的编辑距离(已经知道一些子问题),能推导出哪些字符串之间的最小编辑距离(这些子问题能求解出哪些父问题

在这个问题中,使用第一种思路更简单。
假设要求s3与s4两个字符串之间的最小编辑距离,有下面两种情况:

  • 如果s3与s4的结尾字符相同,那么答案等于s3与s4都去掉结尾字符以后的最小编辑距离(子问题)
  • 如果s3与s4的结尾字符不同,那么先不管前面的那些字符,如何编辑s3使得两个字符串的结尾字符相同呢?测试几个例子能知道,结尾字符最终相同只能有以下3种原因

    • 向s3后面拼接s4的结尾字符。此时,原始s3与s4的最小编辑距离=1+拼接以后的最小编辑距离
    • 删除s3的结尾字符(可能删除以后结尾字符还是不同,不过没关系,这是子问题要处理的事情)。此时,原始s3与s4的最小编辑距离=1+删除以后的最小编辑距离
    • 将s3的结尾字符替换成了s4的结尾字符。此时,原始s3与s4的最小编辑距离=1+替换以后的最小编辑距离

除了以上三种手段以外,不管你如何对s3的前面字符如何增加、删除、替换,都不能让结尾字符相同。

现在将上面结论换成代码表述。假设ed[i][j]表示 word1[0]~word1[i-1]word2[0]~word2[j-1]之间的最小编辑距离

if (word1[i - 1] == word2[j - 1]) ed[i][j] = ed[i - 1][j - 1];
else ed[i][j] = min(min(ed[i][j - 1] + 1, ed[i - 1][j] + 1), ed[i - 1][j - 1] + 1);    // 将3种方法都尝试,取最小的结果

现在有了转移关系,我们只要先计算子问题的结果(较短子串之间的编辑距离)并存储起来,然后用它计算出父问题的结果(较长子串之间的编辑距离),最后就能算出两个完整字符串之间的编辑距离。

代码实现

class Solution
{public:int minDistance(string word1, string word2){const int size1 = word1.size(),size2 = word2.size();if (size1 == 0)return size2;if (size2 == 0)return size1;// ed[i][j]表示 word1[0]~word1[i-1]与word2[0]~word2[j-1]之间的最小编辑距离vector<vector<int>> ed(size1 + 1, vector<int>(size2 + 1, 0));// 初始化任意字符与空字符之间的编辑距离for (int i = 0; i <= size1; i++){ed[i][0] = i;}for (int i = 0; i <= size2; i++){ed[0][i] = i;}for (int i = 1; i <= size1; i++){for (int j = 1; j <= size2; j++){if (word1[i - 1] == word2[j - 1])ed[i][j] = ed[i - 1][j - 1];else// 将3种编辑结尾的方法都尝试,取最小的结果ed[i][j] = min(min(ed[i][j - 1] + 1, ed[i - 1][j] + 1), ed[i - 1][j - 1] + 1);}}return ed[size1][size2];}
};

使用了2层嵌套循环,对每一种word1和word2的前缀的组合都求出了编辑距离,因此时间复杂度是O(n^2)。

在这里,数组ed具有更一般的含义:它是动态规划算法的记忆存储,存储了已经计算出的子问题的答案。更严格地说,其实只需要存储将来可能被父问题用到的计算结果。

算法题解:最小编辑距离(动态规划算法)相关推荐

  1. 算法设计与分析—动态规划算法

    动态规划算法 1.动态规划算法基本思想 2.动态规划算法求解步骤 3. 0-1背包问题 在现实生活中,存在这样一类问题,它们的活动过程不仅可以分成若干阶段,而且在任意一个阶段(不妨设为第i个阶段)以后 ...

  2. 详解动态规划算法(Python实现动态规划算法典型例题)

    动态规划(Dynamic programming) 是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划算法是通过拆分问题,定义问题状态和状 ...

  3. 贪心算法,递归算法,动态规划算法比较与总结

    一般实际生活中我们遇到的算法分为四类: 一>判定性问题        二>最优化问题        三>构造性问题        四>计算性问题 而今天所要总结的算法就是着重解 ...

  4. 1. 通用基础算法(1.7动态规划算法/1.8模拟算法/1.9其他算法)

    7  动态规划算法 动态规划(Dynamic Programming)是求多阶段决策过程(Multistep Decision Process)最优化的一种数学方法,它将问题的整体按时间或空间的特征分 ...

  5. 五大常用算法之二:动态规划算法

    基本概念 动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移.一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划. 基本思想与策略 基本思想与分 ...

  6. lcs算法c语言代码,动态规划算法-LCS

    本讲我们来探讨动态规划算法中一个常见的问题最长公共子序列即LCS(Long Common Sequence). 首先我们来看一下问题描述: 有两个序列X和Y,其中 X = {x1, x2, ..., ...

  7. 算法--01背包问题(动态规划算法) 21-01-30

    问题简述: 给定n种物品和一个容量为C的背包,物品mi的重量为wi,价值为vi,如何分配背包空间使得装入背包的物品总价值最大? 动态规划: 本算法归属于解决动态规划问题,动态规划(Dynamic Pr ...

  8. 五大常用算法之二: 动态规划算法1

    非常有必要看一看: 漫画:什么是动态规划? 详解动态规划--邹博讲动态规划 一.基本概念 动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移.一个决策序列就是在变化的状态中产生出来的,所以, ...

  9. 最小编辑距离 动态规划 python

    m和n的两个字符串,设有以下几种操作:替换(R),插入(I)和删除(D)且都是相同的操作.求转换一个字符串到另一个需要的最少操作数量.这个数量就可以被视为最小编辑距离.如:acd与ace的Editio ...

  10. 【常见笔试面试算法题12】动态规划算法案例分析

    学习交流加 个人qq: 1126137994 个人微信: liu1126137994 学习交流资源分享qq群: 962535112 文章目录 1.暴力搜索方法 2.记忆搜索方法 3.动态规划方法 4. ...

最新文章

  1. iOS autolayout 约束冲突添加symbol breakpoint
  2. ZendStudio中,缺少gbk gb2312编码的解决办法
  3. 探索 vuex 2.0 以及使用 vuejs 2.0 + vuex 2.0 构建记事本应用
  4. 转发高人文章:以前写的一些有关代码签名/时间戳数字证书的东东
  5. mysql error.log 权限_docker-compose 启动mysql 容器时 error.log 无权限访问怎么办?
  6. 51Nod 1314 定位系统
  7. python修改列表指定位置的_Python 基础教程—列表(1)
  8. java 串的顺序存储_算法入门之串的顺序存储表示
  9. 从石头剪刀布浅谈算法的作用
  10. 310. 最小高度树
  11. 那些年 我们都在...
  12. WiFi 连接到网络的过程
  13. oracle erp 用户手册,oracleerp用户手册-mrp
  14. PreferenceScreen移除菜单项
  15. Mac安装PyQt4
  16. 联合循环——30 正式倒送电
  17. 阿里云服务器密码重置
  18. Mysql中使用逗号隔开多张表生成的表实例
  19. MySQL(八):InnoDB 日志缓冲区(Log Buffer)
  20. 周超臣:支付宝的套路是我走过最长的路

热门文章

  1. 虚拟机玩转缓存服务器,Nginx服务器中浏览器本地缓存和虚拟机的相关设置
  2. 十月 android版本分布,安兔兔发布2018年10月份Android手机性能排行榜
  3. css 设置背景图一半_CSS背景图设置
  4. 协方差与相关系数的再理解
  5. java面向对象编程集合边框_Java学习系列(七)Java面向对象之集合框架详解(上)
  6. c语言常用术语,保证让你大开眼界
  7. c语言数据结构-算法篇之选择排序
  8. css实现图片虚化_HTML+CSS入门 如何实现背景图片虚化效果
  9. 信息系统项目管理师学习方法
  10. websphere 启动服务