Edit Distance

2023-11-17

Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

You have the following 3 operations permitted on a word:

a) Insert a character
b) Delete a character
c) Replace a character

编辑距离,非常经典的二维DP题目,也是传说中的双序列问题。

首先定义最优解的表示,f[i][j]表示将word1前i 个字符转化为word2前j个字符需要的step数目(注意为了方便处理初始值,f[0][0] = 0表示空串的最小编辑距离,之后定义最优解之间的转换状态, 即:

f[i][j] = min(f[i][j-1]+1,f[i-1][j]+1,f[i-1][j-1]) (word1[i-1]==word2[j-1])

f[i][j] = min(f[i][j-1]+1,f[i-1][j]+1,f[i-1][j-1]+1) (word1[i-1]!=word2[j-1])

注意在f[i][j-1],f[i-1][j],f[i-1][j-1]都是可以经过1步或者0步到达f[i][j]的子状态(增加word2[j-1],删除word1[i-1],替换(或者不替换)得到f[i][j]。

这种直接的解法代码如下:

class Solution(object):
    def minDistance(self, word1, word2):
        """
        :type word1: str
        :type word2: str
        :rtype: int
        """
        if not word1 and not word2:
            return 0
        l1 = len(word1)
        l2 = len(word2)
        res = [[0 for i in xrange(l2+1)] for j in xrange(l1+1)]
        for i in xrange(1,l1+1):
            res[i][0] = i
        for j in xrange(1,l2+1):
            res[0][j] = j
            
        for i in xrange(1,l1+1):
            for j in xrange(1,l2+1):
                res[i][j] = min(res[i-1][j],res[i][j-1])+1
                if word1[i-1] == word2[j-1]:
                    res[i][j] = min(res[i][j],res[i-1][j-1])
                else:
                    res[i][j] = min(res[i][j],res[i-1][j-1]+1)
        return res[l1][l2]

可以发现这种解法时间复杂度是O(mn),空间复杂度也为O(mn),但是实际计算转换状态时,只需要f[i-1][j],f[i][j-1],f[i-1][j-1]三个值,可以使用之前多次使用的滑动数组(滚动数组来解决)。因为在矩阵每一行从左到右处理,所以如果用一个数组res表示处理到j时,res[j-1]已经更新为f[i][j-1],res[j]还没更新为f[i-1][j-1],唯一需要解决的是res[i-1][j-1]。一个好的办法是使用一个单独的变量pre保存res[i-1][j-1]。在每次更新res[j]时先把 res[j]的历史值存储下来,作为下一次更新要使用的f[i-1][j-1]。另外为了减小空间复杂度可以使res为比较短的单词的长度加1,另外上述代码的三次min可以减少为1次min,即提前对f[i-1][j-1]的情况进行处理,代码如下:

class Solution(object):
    def minDistance(self, word1, word2):
        """
        :type word1: str
        :type word2: str
        :rtype: int
        """
        if not word1 and not word2:
            return 0
        l1 = len(word1)
        l2 = len(word2)
        
        if l1 <= l2: #word1 have the max len
            word1,word2 = word2,word1
            l1,l2 = l2,l1
        res = range(l2+1)
          
        for i in xrange(1,l1+1):
            pre = res[0]
            res[0] = i
            for j in xrange(1,l2+1):
                tmp = res[j]    #缓存f[i-1][j-1]
                if word1[i-1] != word2[j-1]:  #提前处理
                    pre += 1
                res[j] = min(res[j-1]+1,res[j]+1,pre) 
                pre = tmp
                
        return res[l2]
        

 这道题不少人直接使用f[i][j]=f[i-1][j-1](word1[i-1][j-1])和f[i][j]= min(f[i-1][j],f[i][j-1],f[i-1][j-1]+1)这种格式,但是前者的正确性证明我还没有看到特别好的解释。需要后续再想想。

简易版本滚动数组优化:

class Solution(object):
    def minDistance(self, word1, word2):
        """
        :type word1: str
        :type word2: str
        :rtype: int
        """
        if len(word1) == 0 or len(word2) == 0:
            return max(len(word1), len(word2))
        m = len(word1)
        n = len(word2)
        dp = [[0] * (n+1) for i in xrange(2)]
        for i in xrange(1, n+1):
            dp[0][i] = i

        for i in xrange(1, m+1):
            dp[i%2][0] = i
            for j in xrange(1, n+1):
                if word1[i-1] == word2[j-1]:
                    dp[i%2][j] = min([dp[(i-1)%2][j]+1, dp[i%2][j-1]+1, dp[(i-1)%2][j-1]])
                else:
                    dp[i%2][j] = min([dp[(i-1)%2][j]+1, dp[i%2][j-1]+1, dp[(i-1)%2][j-1]+1])            
        return dp[m%2][n]            

 

转载于:https://www.cnblogs.com/sherylwang/p/5522983.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Edit Distance 的相关文章

  • Webpack5 搭建Vue项目(进阶版)

    Webpack5 搭建Vue项目 进阶版 提示 中间隔了好长时间 我胡汉三又回来继续更新了 文章目录 Webpack5 搭建Vue项目 进阶版 前言 一 进阶版本有哪些特点 二 主要的文件代码如下 1 设置一个公共配置 webpack co
  • 使用小工具QuickLook的使用

    终于期末考试结束了 正式步入科研生活 今天正好看到了quicklook这个软件 就顺便下载一下来试试 经常我们困难会为了简单的查看一个文件 却要等待一个大型软件的缓慢加载过程 比如 m ppt文件 在使用这个软件后 不必等待 重型 的 Of
  • 快速从网页爬取图片数据

    1 代码实现 import os import re import time from selenium import webdriver from bs4 import BeautifulSoup from urllib request
  • 数据采集与埋点简介之 代码埋点、可视化埋点与无痕埋点

    转自 https sensorsdata cn blog shu ju jie ru yu mai dian 博主做移动手机系统中的数据采集与埋点也有近两年 那段时间内一方面是集中在具体的开发和问题细节处理 另外一方面则是在把采集系统适配到
  • 数据库性能

    1 建立合理的索引 2 优化SQL语句 3 优化表结构 能用小字段类型就用小字段类型 如能用short就不用int 能用数据类型就不用字符串类型 4 拆分表 横向拆分不更改表结构 重复多建立几张表 纵向拆分影响表结构 通过索引连接多个表 5
  • 2021-03-18-C++学习之17-stack、queue、list

    一 stack容器 1 stack基本概念 stack是一种先进后出 First In Last Out FILO 的数据结构 它只有一个出口 只有顶部元素才可以被外界使用 因此栈不允许有遍历行为 通常有empty函数来判断容器是否为空 s
  • LeetCode 49. 字母异位词分组

    Description 题目大意 给定一个字符串数组 返回字母相同的字符串数组 解题思路 算法标签 哈希表 1 将排序好的字符串设置为key 2 然后存储对应的字符串 代码 class Solution public vector
  • JDBC定义及编程步骤

    0目录 1 JDBC定义 2 为什么需要JDBC 3 JDBC的工作原理 4 JDBC API 5 JDBC编程模板 6 JDBC编程步骤 7 JDBC实战 1 JDBC定义 定义 Java连接数据库的一种能力或者技术 2 为什么需要JDB
  • macos 安装rust

    官方建议使用rustup来安装 rustup可以方便的在不同的rust版本之间切换 brew install rustup 使用rustup安装Rust编译器 rustc 和Rust包管理器 cargo rustup init 执行完上述两
  • 文件上传漏洞靶场upload-labs学习(pass1-pass5)

    Upload Labs学习 0x00 upload labs简介 0x01 upload labs环境搭建 0x02 Pass1 前端判断绕过 0x03 Pass2 content type类型绕过 上传测试 源代码阅读 0x04 Pass
  • 第六篇 VGGNet——模型精讲

    文章目录 模型介绍 网络组成 VGG16 VGG16 pytoch代码实现 版本一 版本二 VGG16详细参数 模型特性 关于dense evaluation 与multi cr
  • 2022 第十四届蓝桥杯模拟赛第一期(题解与标程)

    第十四届蓝桥杯模拟赛第一期 1 二进制位数 问题描述 答案提交 参考答案 2 晨跑 问题描述 答案提交 参考答案 3 调和级数 问题描述 答案提交 参考答案 程序验证 4 山谷 问题描述 答案提交 参考答案 5 最小矩阵 问题描述 答案提交
  • LCD DRM驱动框架分析一

    本文是基于rk3566 rk3568平台 从概念和框架上对LCD DRM驱动框架进行分析 一 DRM Direct Rendering Manager 简介 DRM 是 Linux 目前主流的图形显示框架 相比 FB 架构 DRM 更能适应
  • echarts 富文本的写法

    实现eCharts的 不同柱子不同样式 或系列下的 不同css样式 的匹配 或者 实现 不同柱子添加不同的说明文字 通过params参数判断 使用不同样式 return name4 固定字符1 value 固定字符2 其中 name4 是c
  • buuoj Exec writeup

    题目 十四 题型 web 题目 ACTF2020 新生赛 Exec 来源 buuoj https buuoj cn 思路 操作系统的指令 具体步骤 Step1 发现题目是要我们ping 我们尝试ping一下127 0 0 1 猜测是应用pi
  • MyCAT在Windows 10环境下安装和启动

    1 下载 从如下地址下载mycat的安装包 https github com MyCATApache Mycat Server eg Mycat server 1 6 7 6 release 20210303094759 win tar g
  • Java数组之数组

    一 数组的概述 数组 Array 是多个相同类型数据按一定顺序排列 的集合 并使用一个名字名 并通过编号的方式 对这些数据进行统一管理 数组的常见概念 数组名 下标 或索引 元素 数组的长度 数组本身是引用数据类型 而数组中的元素可以是任何
  • 百度人脸识别C++对接

    一 注册 id 及上载SDK 二 json openssl curl C 11 这个可以从服务器的winC 的SDK包里找 也可以自己找相应源码编译 三 加入下载的 aip cpp sdk 0 8 1 包 错误 C4996 fopen Th
  • 《深入理解计算机系统》(美)布赖恩特(Bryant,R.E.) 等

    书籍 深入理解计算机系统 美 布赖恩特 Bryant R E 等 适合对象 对计算机感兴趣的朋友 需要相关资料的可私信我 2023 09 20更新完成 先上个大纲框架图 第一章 计算机系统漫游 主要知识点 解读全书结构框架 解释OS的原理和
  • 第2章 在网页中使用JavaScript

    第2章 在网页中使用JavaScript 与能够独立执行的C C 等传统语言不同 执行JavaScript代码需要HTML网页环境 在当初开发JavaScript时 Netscape把JavaScript定位为嵌入式Web脚本语言 这种做法

随机推荐

  • 数据科学库——numpy读取本地数据

    轴 在numpy中可以理解为方向 使用0 1 2 数字表示 对于一个一维数组 只有一个0轴 对于2维数组 shape 2 2 有0轴和1轴 对于三维数组 shape 2 2 3 有0 1 2轴 numpy读取数据 CSV Comma Sep
  • 机构运动学分析

    背景介绍 空间机构具有结构紧凑 运动灵活等特点 在航空航天 精密仪器以及工业设备等领域具有广泛的应用 调研发现 机械臂一般采用伺服电机作为动力源 通过空间连杆驱动末端执行器 大大的减轻了工人的劳动强度 本节中主要是针对RSSR空间连杆机构进
  • 计算机考研国家线2021分数线,2021考研分数线和国家线公布时间

    考研国家线总体上分为学术型复试分数线和专业学位类分数线 也就是通常所说的学硕和专硕复试线 考试年份 考研国家线公布时间 2021年 2021年3月中旬左右 2020年 2020年4月13日 2019年 2019年3月15日 2018年 20
  • WPF使用ResourceDictionary

    WPF使用ResourceDictionary 初级篇1 1 首先建立资源字典文件 也就是一个xaml的文件 先添加一个背景色资源代码 2 调用资源资源中的资源 3 使用资源字典中的资源 参考 MSDN
  • GitHub网页 详解

    文章目录 1 登陆后标题栏 2 主页左侧部分 3 设置页面 4 组织页 5 仓库页 6 新建仓库 7 解决冲突 1 登陆后标题栏 下面从左到右 从上到下全部讲述一遍 GitHub图标 点击后跳转到登录后的首页 搜索框 输入关键字 查询相关的
  • 大气压力换算公式_压强单位bar,psi,pa,mpa,kg换算公式

    压强单位 1巴 bar 100000帕 Pa 10牛顿 平方厘米 0 1MPa 是压强的单位 早先气象学中常用毫巴 现在改用等值的国际单位百帕 1帕是1帕斯卡的简称 就是一平方米受到一牛顿的压力 在工程上仍在沿用公斤力这个单位 1公斤力等于
  • 翻译java代码软件_apk源代码翻译器

    APK源代码翻译器 安卓APK代码命令查看工具 是吾爱网友用易语言制作的安卓代码命令查看工具 该工具体积小 但功能强大 欢迎下载使用 软件说明 将apk文件拷贝至sdcard上 命令顺序如下 进入Android sdk文件夹 tools目录
  • 生成 enum 类——数字字典里新增一个按钮 生成他们对应得枚举——java

    前 后 码片 数字字典里新增一个按钮 生成他们对应得枚举 后端 xml 创建一个enum ftl Description dict dictName Author ksf Date now string yyyy MM dd Version
  • sql server 经典练习题分享二

    26 查询存在有85分以上成绩的课程Cno SELECT DISTINCT cno FROM dbo scores WHERE degree gt 85 27 查询出 计算机系 教师所教课程的成绩表 SELECT tname prof cn
  • 23. 客户默认选项(Default Customer Options)

    Editing Email Templates Email Sender Contact Us
  • iphone尺寸_2007至2020:最全的iPhone手机25部历代发展及价格变化历史

    所以iPhone SE 2020 是真的廉价倒地了 智能手机时代的开始 第一代iPhone 2G 2007 4G 3800 8G 4560 2007年 史蒂夫 乔布斯 Steve Jobs 穿着运动鞋 牛仔裤 T恤站在舞台上 宣布了第一部i
  • Maven、pom.xml

    maven库中心 Maven Central Repository Search 搜索可以用的包与版本 目录 Maven 使用方法 1 下载 配置 2 项目中使用 3 生命周期 4 构建插件 MAVEN工程 的目录结构 父子项目 创建父项目
  • dpr-2000 四usb口无线多功能打印服务器,D-Link DPR-2000 超高兼容的打印服务器

    PConline资讯 DPR 2000无线802 11 G多功能打印服务器是一个通用多端口的打印服务器 是办公 学校和商业使用的理想选择 它提供4个USB连接接口可以连接4台USB打印机 本设备给用户提供添加多个打印机 多功能打印机或扫描仪
  • vue项目使用luckyexcel插件预览excel表格

    温馨提示 需要用到luckysheet文件和luckyexcel插件 根据下面步骤一步一步操作会避免踩坑 比如我当时遇到了window luckysheet is not defined控制台报红的问题 第一步 引入luckysheet的相
  • JAVA单元测试框架-14-实现TestNG失败案例重跑

    前面是通过java代码指定重跑 本节是讲解通过实现IAnnotationTransformer接口实现失败案例重跑 创建MyRetry 实现IRetryAnalyzer 接口 package Listener import org test
  • MMsegmentation文档学习

    1 了解配置 config文件结构 config base 下有4种基本组件类型 dataset model schedule default runtime 同一文件夹下的所有配置 建议只具有一个原始配置 所有其他配置从原始配置继承 这样
  • JDK8升级JDK11最全实践干货来了

    1 前言 截至目前 2023年 Java8发布至今已有9年 2018年9月25日 Oracle发布了Java11 这是Java8之后的首个LTS版本 那么从JDK8到JDK11 到底带来了哪些特性呢 值得我们升级吗 而且升级过程会遇到哪些问
  • Ts接口的使用

    TypeScript 的核心原则之一是对值所具有的结构进行类型检查 我们使用接口 Interfaces 来定义对象的类型 接口是对象的状态 属性 和行为 方法 的抽象 描述 接口初探 需求 创建人的对象 需要对人的属性进行一定的约束 id是
  • 工作10年我面试过上百个程序员,真想对他们说…

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 一 写在前面 最近收到不少读者反馈 说自己在应聘一些中大型互联网公司的Java工程师岗位时遇到了不少困惑 这些同学说自己也做了精心准备 网上搜集了不少Java面试题
  • Edit Distance

    Given two words word1 and word2 find the minimum number of steps required to convert word1 to word2 each operation is co