LeetCode刷题之HOT100之编辑距离

2024-06-08 15:28

本文主要是介绍LeetCode刷题之HOT100之编辑距离,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

吃了一份扬州炒饭,等会还要去喝点酒,今天室友生日,下午上课我才反应过来。先做道题再说。
2024/6/8 昨天去喝酒去了,这道题没有做。大概喝到凌晨一点,看了会《地下室手记》,简单洗漱后上床准备休憩。辗转无眠,凌晨五点 天见白,遂去旗山湖走了一圈。放几张风景照。
在这里插入图片描述

图一、渔人撑篙打渔,好不快意

在这里插入图片描述

图二 、旗山准备醒来

在这里插入图片描述

图三 、莲花睡在上面宁静、恬适

在这里插入图片描述

图四、湖光山色,甚美
Anyway,景色看过,那么接下来就做做题。

1、题目描述

在这里插入图片描述

2、逻辑分析

这题以前是hard啊,现在反而被降级了。我是说怎么看不懂,题解也有些看不懂啊。GPT如是说:
算法原理:编辑距离是衡量两个字符串差异的一种指标,表示通过插入、删除和替换操作将一个字符串转换成另一个字符串所需要的最少编辑次数。
步骤:

  1. 初始化:
    如果其中一个字符串为空,那么编辑距离就等于非空字符串的长度,因为需要将空字符串填充成另一个字符串,这需要进行与另一个字符串长度相等的插入操作。

  2. 动态规划:
    这个问题可以使用动态规划(DP)来解决。DP 数组 D 的每个元素 D[i][j] 表示 word1 的前 i 个字符和 word2 的前 j 个字符之间的最小编辑距离。
    初始化DP数组的边界条件:当 word2 为空时,word1 需要删除所有字符才能变为空串,所以 D[i][0] 被初始化为 i 。同理,D[0][j] 被初始化为 j

  3. 填充 DP 数组:
    对于D[i][j] ,有三种可能的操作:
    删除:将 word1 的第 i 个字符删除,此时 D[i][j] 依赖于 D[i-1][j],需要加1表示进行了一次删除操作。
    插入:在 word1 的前 i 个字符后插入 word2 的第 j 个字符,此时 D[i][j] 依赖于D[i][j-1],需要加1表示进行了一次插入操作。
    替换:如果word1的第i个字符和word2的第 j 个字符不同,则将word1的第i个字符替换为word2的第 j 个字符,此时D[i][j]依 赖于 D[i-1][j-1],需要加1表示进行了一次替换操作;如果两者相同,则不需要替换,D[i][j]就等于D[i-1][j-1]
    D[i][j]取上述三种操作中结果最小的那个。

GPT给出得已经较为完备,现在还没懂的原因就是,没有真正的去思考具体步骤。

去csdn找到一个比较清晰的版本,放下图,链接也放过来:详解编辑距离。

在这里插入图片描述
相关代码说明

// 删除操作int left = dp[i - 1][j] + 1;// 插入操作 int up = dp[i][j - 1] + 1;// 替换操作的基础值int left_up = dp[i - 1][j - 1];// 如果字符不同,需要替换,加1if(word1.charAt(i - 1) != word2.charAt(j - 1)){left_up += 1;}// 取三种操作中的最小值dp[i][j] = Math.min(left, Math.min(up, left_up));

那么我们以一个例子来说明具体过程:
如两个单词分别为 dog 和 doge。初始化行和列。

dog
0123
d1
o2
g3
e4

我们需要知道上的值
由于’d’ = ‘d’,两字符相等,我们取三的点最小值即为Math.min(1+1, Math.min( 1+1, 0+0))= 0

dog
0123
d10
o2
g3
e4

下面我们继续,向右遍历:‘d’ != ‘o’,Math.min(0+1, Math.min( 2+1, 1+1)) = 1

dog
0123
d101
o2
g3
e4

以此类推可以得到最终结果

dog
0123
d1012
o2101
g3210
e4321

下面代码演示

3、代码演示

public int minDistance(String word1, String word2) {// word1的长度和world2的长度 int n = word1.length();  int m = word2.length();// 如果有一个字符串为空,则编辑距离等于非空字符串的长度if(n * m == 0){return n + m ;}// 初始化DP数组,大小为(n+1) x (m+1)int [][] dp = new int [n + 1][m + 1];// 初始化DP数组的边界条件 // 当word2为空时,需要删除word1的所有字符for(int i = 0; i < n + 1; i++){dp[i][0] = i;}// 当word1为空时,需要插入word2的所有字符 for(int j = 0; j < m + 1; j++){dp[0][j] = j;}// 填充DP数组的其他元素for(int i = 1; i < n + 1; i++){for(int j = 1; j < m + 1; j++){// 删除操作int left = dp[i - 1][j] + 1;// 插入操作 int up = dp[i][j - 1] + 1;// 替换操作的基础值int left_up = dp[i - 1][j - 1];// 如果字符不同,需要替换,加1if(word1.charAt(i - 1) != word2.charAt(j - 1)){left_up += 1;}// 取三种操作中的最小值dp[i][j] = Math.min(left, Math.min(up, left_up));}}// 返回编辑距离return dp[n][m];        }

4、复杂度分析

  • 时间复杂度:O(mn),两个循环需要的时间,nworld1的长度,mworld2的长度。
  • 空间复杂度:O(mn),需要一个二维数组来保存中间值

5、总结

这题看着不简单,理解起来也确实不简单哈哈,不过最后还是理解了七七八八。Anyway,我要去吃午饭了,这道题做了好久,再见!

这篇关于LeetCode刷题之HOT100之编辑距离的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java计算经纬度距离的示例代码

《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下... 目录1. Haversine公式(中等精度,推荐通用场景)2. 球面余弦定理(简单但精度较低)3. Vincenty公式(高精度,

Python+Tkinter实现Windows Hosts文件编辑管理工具

《Python+Tkinter实现WindowsHosts文件编辑管理工具》在日常开发和网络调试或科学上网场景中,Hosts文件修改是每个开发者都绕不开的必修课,本文将完整解析一个基于Python... 目录一、前言:为什么我们需要专业的Hosts管理工具二、工具核心功能全景图2.1 基础功能模块2.2 进

如何解决Pycharm编辑内容时有光标的问题

《如何解决Pycharm编辑内容时有光标的问题》文章介绍了如何在PyCharm中配置VimEmulator插件,包括检查插件是否已安装、下载插件以及安装IdeaVim插件的步骤... 目录Pycharm编辑内容时有光标1.如果Vim Emulator前面有对勾2.www.chinasem.cn如果tools工

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param