文章目录

  • 题目
  • 解题思路
    • (1)基本过程
    • (2)动态规划-递归
    • (3)动态规划-dp table
  • 代码

题目

leetCode72:编辑距离

编辑距离算法是一个非常实用的算法,它的作用是求出把一个字符串s1变为另一个字符串s2所需要的最少的操作数
此过程中,只能对字符串进行插入、删除或替换(其实还有一种隐形操作,就是略过)

比如把rad变为apple,就需要经过5步

解题思路

(1)基本过程

对于字符串类的题目,一般都会使用到两个指针,这里面也不例外。上面的动图中,展现的正是两个指针i和j分别从后向前扫描两个字符串。
在这个过程中如果j走完了,i还没有走完的话,那么就需要把s1删除,缩短为s2单

如果i走完了,但j没有走完,那么就想要把s2中的插入到s1中

(2)动态规划-递归

使用动态规划解题,一定要考虑题目的状态和选择是什么?

  • 状态:这里显然是i和j指针的位置
  • 选择:所选的操作,加上跳过,共有四种操作(skip,insert,delete,replace
if s1[i]==s2[j]skip;
elseinsert or delete or relace;

还有“base case”,也就是最简单的情况是什么呢?这里其实就是上面所叙述的那两种情况

首先采用递归解法说明。定义一个dp递归函数,函数形参分别就是ij,该函数的返回值就是s1[0....i]s2[0...j]的最小编辑距离,最终一步一步递归,可以得到问题的最终答案。

现在看该函数的base case,也就是如果j走完了,就把i删除了;如果i走完了,就把j剩下的全部插入

int dp(i,j)
{if i==-1return j+1;if j==-1return i+1;
}

如果遇到的字符相等,那么就什么也不做,直接跳过。也即是说s1[0....i]s2[0....j]的最小编辑距离实际就是s1[0...i-1]s2[0....j-1]的最小编辑距离。

int dp(i,j)
{if i==-1return j+1;if j==-1return i+1;if(s1[i]==s[j])return dp[i-1][j-1];else}

如果遇到的字符不相等,那么我们就需要进行选择三种操作了。需要注意的是三种操作是肯定存在重叠问题,这也是递归不可避免的问题,因为一个字符变成另一个字符除了可以替换外,我也可以直接插入一个。

  • 第一种操作:插入;递归函数为dp(i,j-1)+1。如果选择了这种操作,那么就会直接在s1[i]中插入一个和s2[j]一样的字符,此时s2[j]会被匹配到。注意操作数+1

  • 第二种操作:删除;递归函数为dp(i-1,j)+1。如果选择了这种操作,那么就会直接把s[i]这个字符删除掉。

  • 第三种操作:替换;递归函数为dp(i-1,j-1)+1。如果选择了这种操作就会直接把s1[i]替换为s2[j]

于是伪代码如下

int dp(i,j)
{if i==-1return j+1;if j==-1return i+1;if(s1[i]==s[j])return dp[i-1][j-1];elsereturn min(dp(i,j-1)+1;//插入dp(i-1,j)+1;//删除dp(i-1,j-1)+1;//替换)
}

还是那句话,这种解法一定存在大量重叠子问题。比如能过替换得到的结果也可以通过删除后插入完成,这就是一条重复路径,如果发现了一定重复问题,那么一定会有千千万万个重复问题,就像斐波那契数列一样。而重叠子问题是可以通过备忘录解决的

memo=dict();
int dp(i,j)
{if((i,j) in memo)return memo[(i,j)];if i==-1return j+1;if j==-1return i+1;if(s1[i]==s[j])return dp[i-1][j-1];elsereturn min(dp(i,j-1)+1;//插入dp(i-1,j)+1;//删除dp(i-1,j-1)+1;//替换)
}

(3)动态规划-dp table

递归便于说明问题的解决思路,实际写代码时我们一般采用的还是自底向上的解法,也就是动态规划数组。有了上面的基础,我们很容易能够理解,和公共子串,子序列那些题一样**,这道题的数组也一定是一个二维数组**


其中dp[…][0]和dp[0][…]对应的就是base case(也即是把rad变成空串,那么需要3步),dp[i][j]存储的是s1[0…i-1]和s2[0…j-1]的最小编辑距离。(dp函数的base case是i和j为-1,但是数组索引至少为0,所以要偏移1位)

代码

class Solution {public:int minDistance(string word1, string word2) {int len1=word1.size();int len2=word2.size();vector<vector<int>> dp(len1+1,vector<int>(len2+1,0));//dp数组for(int i=1;i<=len1;i++)//base casedp[i][0]=i;for(int j=1;j<=len2;j++)dp[0][j]=j;for(int i=1;i<=len1;i++){for(int j=1;j<=len2;j++){if(word1[i-1]==word2[j-1])dp[i][j]=dp[i-1][j-1];elsedp[i][j]=min//min函数只有两个形参,所以这样写(dp[i-1][j]+1,//插入min(dp[i][j-1]+1,//删除dp[i-1][j-1]+1)//替换);}}return dp[len1][len2];}
};

动态规划经典题之编辑距离相关推荐

  1. 动态规划经典题:给出两个字符串s1和s2,返回其中最大的公共子串

    求公共子字符串问题(连续的) 这个题目是当时远景能源公司现场笔试的一道题目,当时根本就不知道动态规划是什么鬼,直接上来就暴力求解,面试官很谄媚的问我,你这能求出来吗?当时很年轻的说,能啊!现在想,当时 ...

  2. 动态规划经典题之年终奖

    文章目录 题目 解题思路 代码 题目 牛客 解题思路 这道题属于贪心算法,但本质仍然是动态规划.对于这样一个棋盘,到达(i,j)这一点要么是上一行(i-1,j)向下移动一行得到,要么是前一列(i,j- ...

  3. 动态规划经典题之石子合并

    题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分 试设计出1个算法,计算出将N堆石子合并成1堆 ...

  4. HDU OJ 动态规划46题解析

    Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955  背包;第一次做的时候把概率当做背包(放大100000倍化为整数):在此范围内最多能抢 ...

  5. 数据结构与算法 经典题库练习

    文章目录 一.字符串.时间复杂度与逻辑思维训练 1.Z字形变换 2.字符串转换整数(atoi) 3.字符流中第一个不重复的字符 4.小易的英语软件 二.指针.数组.链表组合练习 5.盛最多水的容器 6 ...

  6. 动态规划经典题目汇总

    http://www.cppblog.com/doer-xee/archive/2009/12/05/102629.html 转载之前先Orz一下: [s:19] Robberies http://a ...

  7. 动态规划经典题目——最大子矩阵和

    一.题目 题目描述:现给出一个N*N矩阵,要求求出拥有最大和的子矩阵的和.例子如下图所示: 它的最大子矩阵的和为15: 二.解题思路 此题的解法与动态规划经典题目--最大连续子序列之和题目思想一样,只 ...

  8. ヾ(o◕∀◕)ノヾ各种动态规划经典例题(新手向、多类型)

    ヾ(o◕∀◕)ノヾ各种动态规划经典例题(新手向.多类型) 一.前言 ヾ(・ω・`。)我把比较常见的类型的动态规划找了一些经典的例题,适合作为新手的入门例题,用于帮助我们对各种不同的动态规划有所了解,很 ...

  9. 0-1背包 java_0-1背包问题,java的动态规划如题,代码如下public

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 0-1背包问题,java的动态规划 如题,代码如下 public class dongtaiguihua01 { public static void m ...

最新文章

  1. GitHub发布开源项目指南,以帮助更多开发者参与开源
  2. python猜数游戏流程_Python 猜数字游戏
  3. POJ-1845 Sumdiv 逆元,特殊情况
  4. 【Java】什么是CAS、synchronized升级概述、偏向锁/轻量级锁详解 - 笔记
  5. Java 8 Friday Goodies:Lambda和排序
  6. 得到指定进程所有窗口。显示 影藏 置顶。
  7. java 8 list和数组之间的相互转换
  8. mysql中datetime比较大小问题 (转的)
  9. oracle中序号生成器,Oracle序列生成器
  10. linux 下的下载管理工具
  11. 用“5饼2鱼”分析2019年北美电影票房市场
  12. HTTP Headers
  13. 基于ARM9处理器的工作模式&工作状态&寄存器&异常类型总结笔记
  14. 计算机系统盘没用的东西怎么删除,怎样清理电脑c盘无用的东西
  15. Win10各版本区别
  16. firewalld防火墙配置、测试服务、高级配置与IP伪装、端口转发
  17. python实现百万英雄答题神器
  18. web应用开发平台,微信web开发者
  19. Vue3实现打字机效果
  20. platEMO:一款强大的多目标优化工具(MATLAB)

热门文章

  1. 宣化市大专计算机学校,2018张家口专科大学有哪些 最新大专院校名单
  2. 参考文献中杂志名字问题
  3. AE牛顿动力学插件:Motion Boutique Newton 3 Mac(支持ae2021)
  4. 第48课 加加乐 《小学生C++趣味编程》
  5. 1.5 编程基础之循环控制 20 球弹跳高度的计算
  6. 第28课 叮叮当当 《小学生C++趣味编程》
  7. null未定义_JS 里的数据类型 - null amp; undefined
  8. linux 下的csp 模块,linux kernel 中MIGRATE_TYPES的理解
  9. mysql 结束符报错_【踩坑记录】MySQL 实现自定义递归函数
  10. linux 程序收到sigsegv信号_linux下定位多线程内存越界问题实践总结