【算法-力扣】72. 编辑距离(动态规划)

news2025/4/26 8:22:52

目录

一、题目描述

二、解题思路 

三、参考答案


一、题目描述

      编辑距离

给你两个单词 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 由小写英文字母组成
 

二、解题思路 

   1、首先确定DP数组以及它的含义

        这里我们使用一个二维的DP数组dp[i][j],此时dp[i][j]就表示word1和word2对应的i和j位置结束的时候转换后的最少操作次数。比如word1为abc,word2为dcdb,则dp[1][3]就表示ab转换成dcdb的最少转换次数。这个dp[i][j]的含义一定要记住,不然后面再推导递推公式的时候就很容易把自己绕晕!

   2、如何初始化dp数组

        首先我们要确定,我们要初始化dp数组的哪些位置。因为我们的dp[i][j]表示的是word1和word2对应的i和j位置结束的时候转换后的最少操作次数。所以,最终的我们要的结果也就是dp二维数组的最后一个元素。

 所以,这里我们需要初始化dp数组的第一行和第一列。这样,最终我们才能根据第一行和第一列的数据来推导出来最终的结果。

        那么,问题来了,我们该如何初始化第一行和第一列的数据呢?

       比如,word1为abc,word2为dcdb。我们初始化第一行的时候,那就是要求出a分别转换成d、dc、dcd、dcdb时的最少操作次数。显然这样初始化是非常麻烦的,甚至是不可完成的!那么我们再假设word1为zabc,word2为zdcdb。此时我们初始化第一行的时候,则就是求z分别转换成z、zd、zdc、zdcd、zdcdb时的最少操作次数。显然这个时候就很简单了对应最少操作次数其实就是j的值。

        那么,灵感来了!

        我们只要对word1和word2分别在它的首位置都添加一个相同的字符就行了!因为两个字符相同,所以不会影响我们最终的结果的。此时初始化dp数组就如下:

        // 初始化第一行
        for (int j = 0; j < n; j++)
            dp[0][j] = j;
        // 初始化第一列
        for (int i = 0; i < m; i++)
            dp[i][0] = i;

注:m是word1单词的长度,n是word2单词的长度。 

   3、确定递推公式

  • 当前遍历的dp[i][j]对应word1和word2位置上的字符相等的时候

           dp[i][j] = dp[i-1][j-1] 
      此时不需要任何操作,所以此时的 dp[i][j] = dp[i-1][j-1] 

  • 当前遍历的dp[i][j]对应word1和word2位置上的字符不相等的时候,此时就需要进行操作

        1)插入、删除

        插入和删除操作是等价的,比如a和ab我们删除b和添加b操作次数都是一样的。所以这里我们只考虑删除即可。删除有可能删除word1的i位置的元素,也有可能删除word2的j位置的元素,删除word1和删除word2对应的操作次数是不一样的,所以需要比较出一个操作次数少的。
       删除word1的i位置的元素:dp[i][j] = dp[i-1][j]+1
       删除word2的j位置的元素:dp[i][j] = dp[i][j-1]+1 

       此时在当前操作下的最少操作次数就是:

     dp[i][j] =  Math.min(dp[i-1][j]+1, dp[i][j-1]+1);

      如果此时有点晕,一定要再想dp[i][j]代表的是什么!

       2)替换

       替换也就是将word1在i位置的字符替换成word2在j位置的字符或者是将word2在j位置的字符替换成word1在i位置的字符。不管它俩谁替换谁,我们最终关心的只是操作次数。所以,这里也就是1次操作。所以,我们只要在它们俩前一个位置上的时的最少操作次数上面加1,也就是word1和word2在当前位置和当前替换操作下的最少操作次数了。

        dp[i][j] = dp[i-1][j-1]+1

最后,我们求出这些操作中哪个操作次数最少,也就是我们最终该位置上的最少操作次数了。也就是在word1和word2在i和j位置上的字符不相等的时候的递推公式了。

dp[i][j] =  Math.min( dp[i-1][j-1]+1, Math.min(dp[i-1][j]+1, dp[i][j-1]+1));

三、参考答案

class Solution {
    public int minDistance(String word1, String word2) {
        // 两个字符串前面都加个空字符串,方便后续初始化二维dp数组
        word1 = " " + word1;
        word2 = " " + word2;
        char[] word1Array = word1.toCharArray();
        char[] word2Array = word2.toCharArray();
        int m = word1Array.length, n = word2Array.length;
        // 定义一个dp二维数组,dp[i][j]表示word1和word2对应的i和j位置的时候最少操作次数
        int[][] dp = new int[m][n];
        // 初始化dp数组
        // 初始化第一行
        for (int j = 0; j < n; j++)
            dp[0][j] = j;
        // 初始化第一列
        for (int i = 0; i < m; i++)
            dp[i][0] = i;
        // 遍历
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                // 当当前位置相等的时候
                if (word1Array[i] == word2Array[j]) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else { // 不相等的时候需要处理
                   dp[i][j] = Math.min(Math.min(dp[i][j-1],dp[i-1][j-1]),dp[i-1][j])+1;
                }
            }
        }
        return dp[m-1][n-1];
    }
}

       以上就是使用动态规划解决力扣上72题编辑距离的方法。通过使用动态规划,我们可以高效地解决这个问题,时间复杂度为O(m*n),其中m和n分别是字符串word1和word2的长度。编辑距离是一个非常有意义的问题,掌握了解决方法后,我们就可以将其应用到各种实际问题中,提高算法的效率。编辑距离在我们的实际开发中有很多的应用场景,比如拼写纠错、数据对齐、抄袭侦测等。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win11电脑桌面倒计时提醒怎么设置?

在日常工作中&#xff0c;我们经常需要处理大量的工作任务&#xff0c;而且很多任务都有时间限制。如果将这些任务记录在桌面上&#xff0c;并设置倒计时提醒&#xff0c;无疑会大大提高我们的工作效率。想象一下&#xff0c;在繁忙的工作间隙&#xff0c;你只需一瞥桌面&#…

618火爆来袭,退换货花费多咋办?

姐妹们&#xff0c;一年一度的618就要来了&#xff0c;你准备好了吗&#xff0c;虽然咱们的钱包鼓鼓的&#xff0c;但是咱们的购物袋也要鼓鼓的呀&#xff0c;我们就是要多买&#xff0c;多买&#xff0c;多买&#xff0c;这样才能更显示出自己更爱自己了。 言归正传&#xff…

2024.6.14 刷题总结

2024.6.14 **每日一题** 2786.访问数组中的位置使分数最大&#xff0c;看到这题就想到动态规划的思路&#xff0c;遍历数组&#xff0c;每次选择移动该元素时能获得到的最大值&#xff0c;分别考虑最后一个的元素为奇数/偶数的最大值&#xff0c;用长度为2的数组来储存这两个值…

JUnit 5学习笔记

JUnit 5 学习笔记 1.JUnit5的改变2.JUnit5常用注解及测试2.1 DisplayName/Disabled/BeforeEach/AfterEach/BeforeAll/AfterAll2.2 Timeout2.3 RepeatedTest 3.断言3.1 简单断言3.2 数组断言3.3 组合断言3.4 异常断言3.5 超时断言3.6 快速失败 4.前置条件5.嵌套测试6.参数化测试…

微信群发机器人.使用指南.

0.简介 1.介绍 微信群发机器人是用来群发微信消息的工具,通过控制电脑的键盘和鼠标操作微信app来实现群发.支持的消息类型有:文字,图片,视频,文件,小程序,位置等. 群发机器人也可以将微信联系人中的信息保存到电脑csv表格中,以供分析. 因其是通过模拟用户操作鼠标键盘来实现群…

Java课程设计:基于swing的贪吃蛇小游戏

文章目录 一、项目介绍二、核心代码三、项目展示四、源码获取 一、项目介绍 贪吃蛇是一款经典的休闲益智游戏,自问世以来便深受广大用户的喜爱。这个游戏的基本玩法是控制一条不断增长的蛇,目标是吃掉屏幕上出现的食物,同时避免撞到边缘或自身。随着游戏的进行,蛇的身体会越长…

智慧工厂人员定位系统的影响与前景展望

随着科技的不断发展&#xff0c;智能制造正在迅速崛起&#xff0c;而智慧工厂人员定位系统作为其中的重要组成部分&#xff0c;正在改变传统制造业的面貌。这一系统通过利用物联网、室内定位等技术手段&#xff0c;能够实时准确地追踪和监控工厂内人员的位置。那么&#xff0c;…

Hexapod C-887使用手册 -- 3

3--产品描述 本章中 型号概要 产品视图 交换范围 可选的附件 可命令元素 固件的重要组件 ID芯片探测 轴A和B的操作参数 Hexapod的运动 通过EtherCAT接口发送命令 通信接口 PC软件的概要 3.1 型号概要 C-887 hexapod控制器可以获取以下版本&#xff1a; 型号 描述…

【软件安装9】OpenCV多版本安装Ubuntu18.04

文章目录 一、查看已安装的Opencv版本二、安装新版本三、多版本OpenCV切换 OpenCV 官网 在此 一、查看已安装的Opencv版本 查看已安装opencv的版本 pkg-config opencv --modversion官网下载对应的版本&#xff0c;并解压 opencv3.4.3 二、安装新版本 进入前置准备里下载…

Linux驱动开发笔记(八)输入子系统

文章目录 前言一、输入子系统1. 子系统的引入2. 组成部分3. 事件处理流程4. 相关数据结构 二、程序编写1. 相关API函数1.1 input_allocate_device ( )1.2 input_free_device ( )1.3 input_register_device ( )1.4 input_unregister_device ( )1.5 input_event ( )1.6 input_rep…

ModbusRTU协议之3.5T

RTU 模式每个字节 ( 11 位 ) 的格式为 : 1 起始位&#xff0c; 8 数据位&#xff0c; 1 校验位&#xff08;也可以无校验&#xff09;&#xff0c; 1 停止位&#xff0c; 校验位使用偶校验、奇校验、无校验都可以&#xff0c;但 使用无校验时必须配置 2 个停止位。 所以无…

阿里云的视频超分辨率服务将视频从25M视频增强至469M,画质提升了不少

效果还是不错的&#xff1a; tom&#xff1a; 阿里云文档&#xff1a; 视频超分辨率SuperResolveVideo的语法及示例_视觉智能开放平台(VIAPI)-阿里云帮助中心 请求参数&#xff1a; 还比较简单&#xff0c;就三个参数&#xff0c;其中一个还是固定的&#xff0c;我本次的BitRat…

【SQLAlChemy】表之间的关系,外键如何使用?

表之间的关系 数据库表之间的关系分为三种&#xff1a; 一对一关系&#xff08;One-to-One&#xff09;&#xff1a;在这种关系中&#xff0c;表A的每一行都与表B的一行关联&#xff0c;反之亦然。例如&#xff0c;每个人都有一个唯一的社保号&#xff0c;每个社保号也只属于…

深度学习(六)——神经网络的基本骨架:nn.Module的使用

一、torch.nn简介 官网地址&#xff1a; torch.nn — PyTorch 2.0 documentation 1. torch.nn中的函数简介 Containers&#xff1a;神经网络的骨架 Convolution Layers&#xff1a;卷积层 Pooling layers&#xff1a;池化层 Padding Layers&#xff1a;Padding Non-linear …

android 播放视频

播放视频文件 新建一个activity_main.xml文件&#xff0c;文件中放置了3个按钮&#xff0c;分别用于控制视频的播放、暂停和重新播放。另外在按钮的下面又放置了一个VideoView&#xff0c;稍后的视频就将在这里显示。 <LinearLayout xmlns:android"http://schemas.an…

Android Studio新增功能:Device Streaming

今天将Android Studio升级到2023.3.1 Patch2。发现新增了Device Streaming功能。支持远程使用Google的物理设备调试程序。这样可以方便地在真实设备上测试自己的APP。这对于手头没有Google设备的开发者而言&#xff0c;确实方便很多。该功能目前处于测试阶段&#xff0c;在2025…

【机器学习300问】117、序列模型中的符号表示方法?以命名实体识别(NER)任务为例。

在序列模型中&#xff0c;特别是在命名实体识别(NER)任务中&#xff0c;我们通常会用一系列符号来表示输入序列、目标标签以及模型的结构和操作。本文列出一些常见的符号表示方法&#xff0c;结合NER任务进行解释。 一、什么是命名实体识别任务&#xff1f; &#xff08;1&am…

06 SpringBoot 配置文件详解-application.yaml

Spring Boot 提供了大量的自动配置&#xff0c;极大地简化了spring 应用的开发过程&#xff0c;当用户创建了一个 Spring Boot 项目后&#xff0c;即使不进行任何配置&#xff0c;该项目也能顺利的运行起来。当然&#xff0c;用户也可以根据自身的需要使用配置文件修改 Spring …

L50--- 104. 二叉树的最大深度(深搜)---Java版

1.题目描述 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 2.思路 这个二叉树的结构如下&#xff1a; 根节点 1 左子节点 2 右子节点 3 左子节点 4 计算过程 从根节点 1 开始计算&#xff1a; 计算左子树的最大深度&#xff1a; 根节点 2&#xf…

QTcreator编译器路径错误,no valid kit found

重装系统后&#xff0c;整个QT的应用换了一个盘&#xff0c;但是创建QT工程时默认的编译器路径还是以前的路径且无法修改&#xff0c;创建工程时&#xff0c;出现no valid kit found 可见在option下的编译器相关路径是在E盘且无法更改 进入现在的QT盘进行文件的修改 F:\QT\Too…