LeetCode算法题解(动态规划)|LeetCode583. 两个字符串的删除操作、LeetCode72. 编辑距离

本文主要是介绍LeetCode算法题解(动态规划)|LeetCode583. 两个字符串的删除操作、LeetCode72. 编辑距离,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、LeetCode583. 两个字符串的删除操作

题目链接:583. 两个字符串的删除操作
题目描述:

给定两个单词 word1 和 word2 ,返回使得 word1 和  word2 相同所需的最小步数

每步 可以删除任意一个字符串中的一个字符。

示例 1:

输入: word1 = "sea", word2 = "eat"
输出: 2
解释: 第一步将 "sea" 变为 "ea" ,第二步将 "eat "变为 "ea"

示例  2:

输入:word1 = "leetcode", word2 = "etco"
输出:4

提示:

  • 1 <= word1.length, word2.length <= 500
  • word1 和 word2 只包含小写英文字母
算法分析:
定义dp数组及下标含义:

dp[i][j]表示以下标i结尾的word1字符串和以下标j结尾的word2字符串,删除至相同所需的最小步骤。

递推公式:

如果word1[i]==word2[j],无需进行删除操作,那么dp[i][j] == dp[i-1][j-1];

如果word1[i] !=word2[j],那么dp[i][j]可以由三个方向推导出来:

1、删除word1[i],删除word2[j],两个步骤,即dp[i][j]=dp[i-1][j-1]+2;

2、删除word1[i],word2[j]继续匹配,一个步骤,即dp[i][j]=dp[i-1][j]+1;

3、删除word2[j],word1[i]继续匹配,一个步骤,即dp[i][j]=dp[i][j-1]+1;

所以dp[i][j]=max(dp[i-1][j-1]+2,dp[i-1][j]+1,dp[i][j-1]+1);

初始化:

由递推公式可知,dp需要初始化第一行和第一列。

        for(int j = 0; j < word2.length(); j++){if(word1.charAt(0) == word2.charAt(j)){//如果相等,那么word1[0]和以下标j结尾的word2字符串相同所需的操作步骤为j,即删掉除word2[j]之前的所有字符。dp[0][j] = j;}else{//如果不相等,当j == 0 的时候,需要删除word1[0]和word2[0],2个步骤//当j!=0时,在之前步骤的基础上,删除word2[j],加一个步骤。if(j > 0) dp[0][j] = dp[0][j-1] + 1;else dp[0][j] = 2;}}for(int i = 0; i < word1.length(); i++){//第一列同理if(word1.charAt(i) == word2.charAt(0)){dp[i][0] = i;}else{if(i > 0) dp[i][0] = dp[i-1][0] + 1;else dp[i][0] = 2;}}
遍历顺序:

word1和word2的哪个先遍历都无所谓,只要都是从前往后遍历。

打印dp数组进行验证。

代码如下:

class Solution {public int minDistance(String word1, String word2) {int[][] dp = new int[word1.length()][word2.length()];for(int j = 0; j < word2.length(); j++){if(word1.charAt(0) == word2.charAt(j)){//如果相等,那么word1[0]和以下标j结尾的word2字符串相同所需的操作步骤为j,即删掉除word2[j]之前的所有字符。dp[0][j] = j;}else{//如果不相等,当j == 0 的时候,需要删除word1[0]和word2[0],2个步骤//当j!=0时,在之前步骤的基础上,删除word2[j],加一个步骤。if(j > 0) dp[0][j] = dp[0][j-1] + 1;else dp[0][j] = 2;}}for(int i = 0; i < word1.length(); i++){//第一列同理if(word1.charAt(i) == word2.charAt(0)){dp[i][0] = i;}else{if(i > 0) dp[i][0] = dp[i-1][0] + 1;else dp[i][0] = 2;}}for(int i = 1; i < word1.length(); i++) {for(int j = 1; j < word2.length(); j++) {if(word1.charAt(i) == word2.charAt(j)){//相等时由左上方推出来dp[i][j] = dp[i-1][j-1];}else{//不相等时由左方、上方、左上方推出来dp[i][j] = Math.min(dp[i-1][j-1] + 2,Math.min(dp[i-1][j] + 1,dp[i][j-1] + 1));}}}return dp[word1.length()-1][word2.length()-1];}
}

二、LeetCode72. 编辑距离

题目链接:72. 编辑距离
题目描述:

给你两个单词 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 由小写英文字母组成
算法分析:
定义dp数组及下标含义:

dp[i][j]表示以下标i结尾的字符串word1转换成以下标j结束的字符串word2所需的最少操作步骤。

递推公式:

当word1[i]==word2[j]时,无需任何操作,即dp[i][j]=dp[i-1][j-1];

当word1[i]!=word2[j]时,可以有三种操作:

1、替换word1[i]元素,使之与word2[j]相等,即dp[i][j]=dp[i-1][j-1]+1;

2、删除word1[i]元素,即dp[i][j]=dp[i-1][j] + 1;

3、在word1[i]元素之后插入一个元素,使该元素与word2[j]相等,那么即dp[i][j]=dp[i][j-1]+1;

初始话:

根据递推公式初始化dp数组的第一行和第一列。

        boolean flag = false;for(int j = 0; j < word2.length(); j++) {if(word1.charAt(0) == word2.charAt(j)){//如果相等,那么word1[0]转化成以j结尾的word2字符串所需操作数为j,即添加j个数,注意j是从0开始的。dp[0][j] = j;flag = true;}else{//如果不相等,当word2[j]之前有出现过word1[0]时,只需操作j步,即在word1[0]添加j个数//当word2[j]之前没有出现果word1[0]时,需要操作j+1步,即将word1[0]转化成word1[0],再添加j个数if(flag) dp[0][j] = j;else dp[0][j] = j + 1;}}flag = false;for(int i = 0; i < word1.length(); i++) {//初始化第一列同理if(word1.charAt(i) == word2.charAt(0)){dp[i][0] = i;flag = true;}else{if(flag) dp[i][0] = i;else dp[i][0] = i + 1;}}
遍历顺序:

word1和word2哪个先遍历没关系,但都需从前往后遍历。

打印dp数组进行验证。

代码如下:

class Solution {public int minDistance(String word1, String word2) {if(word1.length() == 0) return word2.length();if(word2.length() == 0) return word1.length();int[][] dp = new int[word1.length()][word2.length()];boolean flag = false;for(int j = 0; j < word2.length(); j++) {if(word1.charAt(0) == word2.charAt(j)){//如果相等,那么word1[0]转化成以j结尾的word2字符串所需操作数为j,即添加j个数,注意j是从0开始的。dp[0][j] = j;flag = true;}else{//如果不相等,当word2[j]之前有出现过word1[0]时,只需操作j步,即在word1[0]添加j个数//当word2[j]之前没有出现果word1[0]时,需要操作j+1步,即将word1[0]转化成word1[0],再添加j个数if(flag) dp[0][j] = j;else dp[0][j] = j + 1;}}flag = false;for(int i = 0; i < word1.length(); i++) {//初始化第一列同理if(word1.charAt(i) == word2.charAt(0)){dp[i][0] = i;flag = true;}else{if(flag) dp[i][0] = i;else dp[i][0] = i + 1;}}for(int i = 1; i < word1.length(); i++) {for(int j = 1; j < word2.length(); j++) {if(word1.charAt(i) == word2.charAt(j)) {//如果相等,无需操作dp[i][j] = dp[i-1][j-1];}else{//如果不相等,再三个操作当中取步骤最少的操作数。dp[i][j] = Math.min(dp[i-1][j-1] + 1, Math.min(dp[i-1][j] + 1, dp[i][j-1] + 1));}}}// for(int i = 0; i < word1.length(); i++) {//     for(int j = 0; j < word2.length(); j++) {//         System.out.print(dp[i][j] + " ");//     }//     System.out.println();// }return dp[word1.length()-1][word2.length()-1];}
}

总结

这两道题比较类似,只要会其中一道题,两外一个也很容易想出来。

这篇关于LeetCode算法题解(动态规划)|LeetCode583. 两个字符串的删除操作、LeetCode72. 编辑距离的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/462670

相关文章

Mysql实现范围分区表(新增、删除、重组、查看)

《Mysql实现范围分区表(新增、删除、重组、查看)》MySQL分区表的四种类型(范围、哈希、列表、键值),主要介绍了范围分区的创建、查询、添加、删除及重组织操作,具有一定的参考价值,感兴趣的可以了解... 目录一、mysql分区表分类二、范围分区(Range Partitioning1、新建分区表:2、分

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

python删除xml中的w:ascii属性的步骤

《python删除xml中的w:ascii属性的步骤》使用xml.etree.ElementTree删除WordXML中w:ascii属性,需注册命名空间并定位rFonts元素,通过del操作删除属... 可以使用python的XML.etree.ElementTree模块通过以下步骤删除XML中的w:as

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2