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];
    }
};
相关推荐
lwf0061641 小时前
逻辑回归学习笔记-梯度下降求解回归方程
算法·机器学习·逻辑回归
郝学胜-神的一滴1 小时前
从底层看透Linux高性能服务器:epoll自定义封装与超时清理实战
linux·服务器·c++·网络协议·tcp/ip·unix
tjc199010051 小时前
Golang怎么实现分布式定时任务_Golang如何保证集群中定时任务不重复执行【进阶】
jvm·数据库·python
卷心菜狗1 小时前
Python进阶--网络编程入门
python
人道领域1 小时前
【LeetCode刷题日记】1047:双栈法与双指针法巧妙消除相邻重复字符
java·算法·leetcode·职场和发展
Via_Neo1 小时前
Bash Game
开发语言·bash
切糕师学AI1 小时前
布隆过滤器(Bloom Filter)技术详解
数学·算法
XLYcmy2 小时前
2026游戏安全技术竞赛-PC客户端安全-初赛 求解起点到终点的最短路径
windows·python·网络安全·dfs·bfs·游戏安全·曼哈顿距离
礼拜天没时间.2 小时前
力扣热题100实战 | 第33期:搜索旋转排序数组——二分查找的变体艺术
算法·leetcode·职场和发展·旋转数组·搜索旋转排序数组