LeetCode72.编辑距离(多维动态规划)

题目LeetCode 72

给你两个单词 word1word2请返回将 word1 转换成 word2 所使用的最少操作数

你可以对一个单词进行如下三种操作:

插入一个字符

删除一个字符

替换一个字符

示例

示例 1:

输入: word1 = "horse", word2 = "ros"
输出: 3
解释:

horse -> rorse (将 'h' 替换为 'r')

rorse -> rose (删除 'r')

rose -> ros (删除 'e')

Python解法

代码示例

python 复制代码
class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        n, m =len(word1), len(word2)
        
        dp = [[0] * (m + 1) for _ in range(n + 1)]
        for i in range(n + 1):
            dp[i][0] = i
        for j in range(m + 1):
            dp[0][j] = j

        for i in range(1,n + 1):
            for j in range(1,m + 1):
                delete_dp = dp[i - 1][j] + 1
                insert_dp = dp[i][j - 1] + 1
                replace_dp = dp[i - 1][j - 1]
                if word1[i - 1] != word2[j - 1]:
                    replace_dp += 1
                dp[i][j] = min(delete_dp, insert_dp, replace_dp)

        return dp[n][m]

解释

1,边界初始化

python 复制代码
for i in range(n + 1):
    dp[i][0] = i

word2 为空串,只能把 word1 逐个删除:有几个字符就删几次。

python 复制代码
for j in range(m + 1):
    dp[0][j] = j

word1 为空串,只能逐个插入 word2 字符:有几个字符就插几次。

2,状态转换

(1)删除操作

python 复制代码
delete_op = dp[i - 1][j] + 1

word1 删掉第 i 个字符,问题缩小为:word1前i-1个 匹配 word2前j个,操作 + 1。

(2)插入操作

python 复制代码
insert_op = dp[i][j - 1] + 1

word1 插入一个字符匹配 word2[j-1],问题缩小为:word1前i个 匹配 word2前j-1个,操作 + 1。

(3)替换操作

python 复制代码
replace_op = dp[i - 1][j - 1]
if word1[i - 1] != word2[j - 1]:
    replace_op += 1

如果 word1[i-1] == word2[j-1]:字符相等,不用操作 ,直接继承 dp[i-1][j-1]

如果不相等:替换一次,操作数 + 1

(4)取最小值

python 复制代码
dp[i][j] = min(delete_op, insert_op, replace_op)

三种操作选步数最少的。

过程简单演示

word1 = "ho"word2 = "ro" 为例

Java解法

代码示例

java 复制代码
class Solution {
    public int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();

        // dp[i][j]:word1前i个字符 → word2前j个字符 的最小编辑距离
        int[][] dp = new int[n + 1][m + 1];

        // 边界初始化:word2 为空,只能删除 word1
        for (int i = 0; i <= n; i++) {
            dp[i][0] = i;
        }

        // 边界初始化:word1 为空,只能插入 word2
        for (int j = 0; j <= m; j++) {
            dp[0][j] = j;
        }

        // 动态规划填表
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                // 删除操作:删掉 word1 第 i 个字符
                int delete = dp[i - 1][j] + 1;
                // 插入操作:给 word1 插入一个字符匹配 word2 第 j 个
                int insert = dp[i][j - 1] + 1;
                // 替换 / 不操作:看末尾字符是否相等
                int replace = dp[i - 1][j - 1];
                if (word1.charAt(i - 1) != word2.charAt(j - 1)) {
                    replace++;
                }

                // 三种操作取最小
                dp[i][j] = Math.min(Math.min(delete, insert), replace);
            }
        }

        return dp[n][m];
    }
}

C++解法

代码示例

cpp 复制代码
class Solution {
public:
    int minDistance(string word1, string word2) {
        int n = word1.size();
        int m = word2.size();

        // dp[i][j]:word1前i个字符 转为 word2前j个字符 的最小编辑距离
        vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));

        // 边界1:word2为空,只能不断删除word1
        for (int i = 0; i <= n; ++i) {
            dp[i][0] = i;
        }

        // 边界2:word1为空,只能不断插入word2
        for (int j = 0; j <= m; ++j) {
            dp[0][j] = j;
        }

        // 遍历填充DP表
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                // 1. 删除操作
                int del = dp[i - 1][j] + 1;
                // 2. 插入操作
                int ins = dp[i][j - 1] + 1;
                // 3. 替换 / 无需操作
                int rep = dp[i - 1][j - 1];

                // 当前字符不同,需要替换,操作数+1
                if (word1[i - 1] != word2[j - 1]) {
                    rep += 1;
                }

                // 取三种操作最小值
                dp[i][j] = min({del, ins, rep});
            }
        }

        return dp[n][m];
    }
};
相关推荐
GKxx几秒前
在 HarmonyOS 上从源码构建 GCC 16(gcc/g++ + libstdc++ + libsanitizer):完整记录
c++·华为·harmonyos·鸿蒙·gcc
晴天的雨.9922 分钟前
类和对象下(内部类,匿名对象,对象拷贝时的编译器优化)
开发语言·c++·算法
陈年老古董6 分钟前
PyTorch 实现 MNIST 手写数字识别学习笔记
笔记·python·深度学习·学习
其实防守也摸鱼6 分钟前
智能体推荐:精选 AI Agent 工具与实战指南
运维·开发语言·人工智能·学习·web安全·自动化
SimonKing6 分钟前
开源神器 Navop:数据库+SSH+终端+AI,一个应用全搞定
java·后端·程序员
always_TT6 分钟前
【Python 字符串格式化:format() 方法】
android·开发语言·python
爱码猿10 分钟前
SpringBoot+MybatisPlus动态数据源
java·spring boot·后端
小义_11 分钟前
JDK 深度解析
java·linux·开发语言·python·面试
SendTomo14 分钟前
send.wang:基于浏览器WebRTC实现无客户端文件互传
网络·python·网络协议·webrtc·p2p
旖旎夜光21 分钟前
LeetCode 238:除自身以外数组的乘积(前缀和) —— 题解
数据结构·c++·算法·leetcode·前缀和