算法学习之动态规划(leetcode 72. Edit Distance)

本文详细解析了LeetCode上的经典题目“编辑距离”(Edit Distance),介绍了如何利用动态规划求解两个字符串之间的最小编辑距离,包括插入、删除和替换操作,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0x01题目
72. Edit Distance
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
0x02解析

写在前面:自己在做这个题目的时候,没有考虑到动态规划的思想,只是想当然的去直观地解决问题,最后发现无法直观解决。在动态规划中最重要的一个思想是建模,建立一个概念。
具体解析:定义dp[i][j],其含义为word1[0 ... i-1]转化成word2[0 ... j-1]的步数,其值分为两类,第一种是边界值,第二种是一般值。
边界值的获取过程如下,如dp[0][j]代表的含义为空字符串""转化成word2[0 ... j-1]的步数,显然为j;同理,dp[i][0]代表的含义为word1[0 ... i-1]转化成空字符串""的步数,显然为i
一般值的获取过程如下,假设我们已经得到了dp[i-1][j-1],如何得到dp[i][j]呢?分如下情况讨论。
(1)当word1[i-1] == word2[j-1]时。此种情况下,只需要将word1[0 ... i-2]转化为word2[0 ... j-2]即可(最后一个字符相同),因此dp[i][j] = dp[i-1][j-1]
(2)当word1[i-1] != word2[j-1]时。此种情况下,根据题中给出的条件,分为以下三种情况(核心都是将word1转化成word2

  1. 在word1中插入字符
    首先将word1[0 ... i-1]转化为word2[0 ... j-2]dp[i][j-1]),然后在word1[0 ... i-1]插入字符为word2[j-1],即word1[0 ... i-1] => word2[0 ... j-2] 且插入 word2[j-1]dp[i][j] = dp[i][j-1] + 1
  2. 在word1中删除字符
    首先将word1[0 ... i-2]转化为word2[0 ... j-1]dp[i-1][j]),然后将字符word1[i-1]删除,即word1[0 ... i-2]=>word2[0 ... j-1] 且删除 word1[i-1]dp[i][j] = dp[i-1][j] + 1
  3. 在word1中替换字符
    首先将word1[0 ... i-2]转化为word2[0 ... j-2]dp[i-1][j-1]),然后将用word2[j-1]替换字符word1[i-1],即word1[0 ... i-2] => word2[0 ... j-2] 且 word1[i-1] => word2[j-1]dp[i][j] = dp[i-1][j-1] + 1
0x03代码

根据以上总结,可以得出的代码如下

public class Solution {
    public int minDistance(String word1, String word2) {
        if(word1 == null || word2 == null) return 0;

        int len1 = word1.length(), len2 = word2.length();
        int[][] dp = new int[len1 + 1][len2 + 1];
        dp[0][0] = 0;
        for(int i = 1; i <= len1; i++){
            dp[i][0] = i;
        }
        for(int j = 1; j <= len2; j++){
            dp[0][j] = j;
        }

        for(int x = 1; x <= len1; x++){
            for(int y = 1; y <= len2; y++){
                if(word1.charAt(x - 1) == word2.charAt(y - 1)){
                    dp[x][y] = dp[x - 1][y - 1];
                }
                else{
                    dp[x][y] = Math.min(Math.min(dp[x - 1][y - 1] + 1, dp[x - 1][y] + 1), dp[x][y - 1] + 1);
                }
            }
        }

        return dp[len1][len2];
    }
}

参考 https://discuss.leetcode.com/topic/17639/20ms-detailed-explained-c-solutions-o-n-space

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值