leetcode72. 编辑距离(动态规划-java)

news2024/11/16 20:57:39

编辑距离

  • leetcode72. 编辑距离
  • 题目描述
    • 解题思路
      • 代码演示
    • 动态规划
      • 代码演示
  • 动态规划专题

leetcode72. 编辑距离

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/edit-distance

题目描述

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

解题思路

如果看到这题,刚开始想不到动态规划的状态转移公式,可以先尝试用暴力递归写出暴力尝试,然后去改写成动态规划,

首先看暴力递归如何写,题目交代了。转化有三个操作,删除替换和插入。还有一个隐藏操作,就是字符相同时。要跳过。这样就是一个完整的操作,这几个操作怎么反应到代码中呢,我们用指针卡住两个单词的起始位置或者终点位置,然后一个一个字符去比较,相等,我们就跳过,不等就替换删除或者插入的操作。

//伪代码框架
if (word1.charAt(r1) == word2.charAt(r2)){
	//啥都不做,跳过,直接去下一个位置操作。
	process(r1 - 1.r2 - 2);
}else {
	//插入,插入后,word2 的指针移动,word1的保持不动
	process(r1,r2 - 1) + 1;
	//删除 ,word1 的指针移动,word2的保持不动
	process(r1 - 1,r2) + 1;
	//替换 word1 和qword2 指针都移动
	process(r1 - 1,r2 - 1) + 1;
	//为甚加1,递归后的可能要加上当前字符
}

根据上面伪代码,我们可以进行写出暴力递归的尝试了。只需要补充上base case,是不是很简单,网上很多资料直接上动态规划,看的头大也看不懂。
我们这题,从尾部开始向前去比较操作,你也可以从头往后比较,区别就是,base case .和指针移动方向步一样,你可以自己改写下。

代码演示


    /**
     * 最小编辑距离
     * @param word1
     * @param word2
     * @return
     */
    public int minDistance(String word1, String word2) {
        if (word1.length() == 0){
            return word2.length();
        }
        if (word2.length() == 0){
            return word1.length();
        }
        if (word1.equals(word2)){
            return 0;
        }
        int n = word1.length();
        int m = word2.length();
        int[][]dp = new int[n][m];
        return process(word1.toCharArray(),n -1,word2.toCharArray(),m - 1,dp);
    }

    /**
     * 暴力递归加上缓存,减少重复计算,不加缓存,提交会超时
     * @param word1
     * @param r1 word1 的指针
     * @param word2
     * @param r2 指针
     * @param dp 缓存表
     * @return
     */
    public int process(char[]word1,int r1,char[]word2,int r2,int[][]dp){
        //base case 同时来到-1 ,说明比较完了.返回0
        if (r1 == -1 && r2 == -1){
            return 0;
        }
        //base case r1 结束了,剩下就需要操作r2 的长度,r2 是下标,计算长度要加1
        if (r1 == -1){
            return r2 + 1;
        }
        //base case r2 结束了,剩下就需要操作r1 的长度,r1 是下标,计算长度要加1
        if (r2 == -1){
            return r1 + 1;
        }
        //缓存里有就直接拿
        if (dp[r1][r2] != 0){
            return dp[r1][r2];
        }
        int res = -1;
        if(word1[r1] == word2[r2]){
            //跳过
            res = process(word1,r1 - 1,word2,r2 - 1,dp);
        }else{
            //插入
            int p1 = process(word1,r1,word2,r2 - 1,dp);
            //删除
            int p2 = process(word1,r1 - 1,word2,r2,dp);
            //替换
            int p3 = process(word1,r1 - 1,word2,r2 - 1,dp);
            //要取最小的情况
            res =  Math.min(Math.min(p1,p2),p3) + 1;
        }
        //答案保存到缓存里
        dp[r1][r2] = res;
        return res;
    }

动态规划

看懂了暴力递归,改动态规划应该就很容易了,不过还是加个表格演示下。
更容易明白如何初始化dp 表。

在这里插入图片描述
我们可以把dp表中两边为0位置时,需要操作的长度就是字符的长度,可以直接填上,剩下位置就可以按暴力递归中的依赖关系去填上了。

代码演示

 public int minDistance(String word1, String word2){
        if (word1.length() == 0){
            return word2.length();
        }
        if (word2.length() == 0){
            return word1.length();
        }
        if (word1.equals(word2)){
            return 0;
        }
        int n = word1.length();
        int m = word2.length();
        int[][]dp = new int[n + 1][m + 1];
        //初始化第一列
        for (int i = 1; i <= n ;i++){
            dp[i][0]  = i;
        }
        /初始化第一行
        for (int j = 1;j <= m;j++){
            dp[0][j] = j;
        }
        //递归改成表中拿值得过程
        for (int i = 1; i <= n;i++){
            for (int j = 1; j <= m;j++){
                if(word1.charAt(i - 1) == word2.charAt(j - 1)){
                    dp[i][j] = dp[i - 1][j - 1];
                }else{
                    //插入
                   int p1 = dp[i][j - 1]; 
                   //删除
                   int p2 = dp[i - 1][j];
                   //替换\
                   int p3 = dp[i - 1][j - 1];
                   dp[i][j] = Math.min(Math.min(p1,p2),p3) + 1;
                }
            }
        }
        return dp[n][m];
    }

动态规划专题

leetcode1049. 最后一块石头的重量 II

leetcode123. 买卖股票的最佳时机 III

leetcode188. 买卖股票的最佳时机 IV

leetcode312. 戳气球

eetcode787. K 站中转内最便宜的航班

leetcode62. 不同路径

leetcode63. 不同路径 II

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

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

相关文章

关于DMS批量导入的注意事项

前言 当你注意了列命和数据库对应关系&#xff0c;批量后报错&#xff0c;常见的是无列名都好找问题&#xff0c;说一条不好找的 SQL解析失败:解析文件失败::读取字段定义异常&#xff0c;字段定义存在非法的空字段&#xff0c;请检查提交的Excel文件首行中的字段定义1、列名…

springboot本机启动elasticjob抛出异常HostException(ip is null)

1.使用的elasticjob版本为3.0.1 2.本机的IPV4在校验isReachable 返回false&#xff08;可能是使用无线网&#xff0c;导致ip验证问题&#xff09; 3.最后引入Groovy解决 引入包 <dependency><groupId>org.codehaus.groovy</groupId><artifactId>gr…

【CSS3系列】第九章 · 响应式布局和BFC

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

OpenCV快速生成带边缘的棋盘格

import numpy as np import cv2 as cv# 生成棋盘格 def generateChessBoard(xSize32,ySize32,w6,h6)::param xSize: 棋盘尺寸:param ySize: 棋盘尺寸:param w: 横向角点个数:param h: 纵向角点个数:return:w,hw1,h1boardnp.zeros((xSize*(w),ySize*(h),3),np.uint8)board.fill(…

【网页复习】4道大题

&#x1f38a;专栏【 前端易错合集】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f354;实现如图的导航栏⭐代码&#x1f384;注…

多元分类预测 | Matlab萤火虫算法(FA)优化极限学习机(ELM)的分类预测,多特征输入模型。FA-ELM分类预测模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab萤火虫算法(FA)优化极限学习机(ELM)的分类预测,多特征输入模型。FA-ELM分类预测模型 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,程…

6 中断概览

目录 中断概览 STM32异常和中断介绍 STM32的异常一览 STM32的中断表一览 中断的优先级 中断的优先级分组 优先级分组 嵌套向量中断控制器(NVIC)功能 中断概览 什么是中断&#xff1f; 中断是指计算机运行过程中&#xff0c;出现某些意外情况需主机干预时&#xff0c;机器…

Acer宏碁笔记本电脑 暗影骑士AN515-54原厂Win10系统工厂模式恢复出厂OEM原装预装系统

Acer宏基笔记本电脑&#xff0c;Acer宏碁暗影骑士AN515-54原装出厂Windows10系统恢复原厂OEM系统镜像 系统自带所有驱动、Office办公软件、出厂主题壁纸LOGO、 Acer Care Center、Quick Access、 NitroSense风扇控制等预装程序 所需要工具&#xff1a;32G或以上的U盘&#xf…

Selenium教程__获取浏览器名称和版本(5)

通过学习本文内容&#xff0c;将能够轻松地获取并利用浏览器的信息&#xff0c;从而更好地适应不同的浏览器环境&#xff0c;并确保您的代码和测试脚本能够在各种浏览器中正常运行。 from selenium import webdriverdriver webdriver.Chrome() driver.maximize_window() dri…

SpringSecutiry整合thymeleaf模板

如何构建SpringSecutiry框架&#xff0c;这里就不详细赘述了&#xff0c;直接速通。 目录 thymeleaf教程&#xff08;转载&#xff09; 所需的依赖 Thymeleaf模板文件 具体的项目搭建 资源展览图 接口展示 Thymeleaf模板内容展示 thymeleaf教程&#xff08;转载&#xff09…

uAvionix开始首次FCC授权的C波段无人机数据链BVLOS飞行

2023年6月19日消息&#xff0c;uAvionix是一家为有人和无人驾驶飞机提供指挥、导航和监视技术的领先供应商&#xff0c;该公司今天宣布已获得FCC批准&#xff0c;并与FAA协调&#xff0c;在俄克拉荷马州Choctaw Nation新兴技术试验场运行其SkyLink C波段指挥和控制(C2)无线电&a…

netwox 基于 Ethernet 层构造 IP 数据包【网络工程】(保姆级图文)

目录 基于 Ethernet 层构造 IP 数据包1) 不指定选项&#xff0c;直接运行该模块&#xff0c;查看默认设置。执行命令如下&#xff1a;3) 验证构造的数据包&#xff0c;使用 Wireshark 工具捕获数据包&#xff0c;如图所示。其中&#xff0c;第 2 个数据包为构造的 IPv4 数据包。…

单元测试-sonarqube本地安装使用

sonarqube sonarqube是什么 SonarQube是一个开源的代码分析平台&#xff0c;用来持续分析和评测项目源代码的质量。通过SonarQube我们可以检测出项目中重复代码&#xff0c;潜在bug,代码规范&#xff0c;安全性漏洞等问题&#xff0c;并通过SonarQube web UI展示出来。 Sona…

ESC1+ESC4+CVE-2022–26923

CVE-2022–26923 创建机器账户并指定dnsHostName为dc的域名 certipy account create -u certhacktest.com -p Admin123456. -dc-ip 10.211.55.3 -user win -pass win123456 -dns DC.hacktest.com 用该机器账户向ADCS请求证书 certipy req -u win$hacktest.com -p win123456…

毕业设计之图书馆座位预约系统

1.系统开发环境 系统采用的集成开发环境为IDEA&#xff0c;使用JAVA语言及SPRINGBOOT框架进行开发&#xff0c;其中硬件环境和软件环境如下&#xff1a; 2.硬件环境 处理器&#xff1a;Intel(R) Core(TM) i7-9750 GPU 3.00GHz 内存&#xff1a;8GB 3.软件环境 操作系统&…

【无标题】实时系统Preempt RT与Xenomai之争!谁更主流,谁更实时?

选择争论一直存在 大家知道EtherCAT是实时现场总线技术&#xff0c;当我们开发一款支持EtherCAT总线的控制器时&#xff0c;实时操作系统的选择不仅对于产品本身是最重要的一部分&#xff0c;而且对产品研发的整个过程也影响深远。 根据EtherCAT主站提供商Acontis公司对全球新客…

【ssh】pycharm链接远程服务器出现:Bad owner or permissions on C:\\Users\\用户名/.ssh/config

一直以来是用的pycharm&#xff0c;最近改用了vscode登录&#xff0c;并配置了config文件实现了vscode自动连接远程服务器&#xff0c;但是回到pycharm发现terminal端口不管用了&#xff0c;电脑上的powershell也是链接不上远程服务器并报错Bad owner or permissions。 【解决…

算法06-搜索算法

算法0X-XX 总结大纲要求搜索算法-深度优先搜索例1:全排列放置扑克牌的案例n皇后案例 搜索算法-广度优先搜索 总结 本系列为C算法学习系列&#xff0c;会介绍 算法概念与描述&#xff0c;入门算法&#xff0c;基础算法&#xff0c;数值处理算法&#xff0c;排序算法&#xff0…

Vue3学习(四)服务器部署

注意后端SpringBoot需要提前安装Java1.8的环境和Mysql5.7的数据库 SpringBoot 打包后Jar包需要配置数据库 application.yml 文件 配置服务器数据库的IP和密码 ifconfig 查看内网IP&#xff0c;然后配置。 Vue配置 .env.prod VITE_ENV prod VITE_BASE_URL http://qing.vu…

线性回归与逻辑回归

文章目录 介绍1 实现简单示例函数1.1 提交解决方案 2 单变量线性回归2.1 绘制数据接下来需要实现数据可视化的代码&#xff0c;该部分数据绘制出的图像应与如下相同 2.2 梯度下降2.2.2 实现2.2.3 计算成本J(θ)2.2.4 梯度下降2.3 可视化成本函数 选做练习3 多变量线性回归3.1 特…