【Hot 100 刷题计划】 LeetCode 72. 编辑距离 | C++ 经典 DP 增删改状态转移

LeetCode 72. 编辑距离

📌 题目描述

题目级别:困难 (大厂极高频)

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

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

  1. 插入一个字符
  2. 删除一个字符
  3. 替换一个字符
  • 示例 1:
    输入:word1 = "horse", word2 = "ros"
    输出:3
    解释:
    horse -> rorse (将 'h' 替换为 'r')
    rorse -> rose (删除 'r')
    rose -> ros (删除 'e')

💡 破题思路:二维动态规划

编辑距离是字符串 DP 的终极 Boss,但只要拆解开它的状态转移,逻辑其实非常清晰。

状态定义:

定义 f[i][j] 表示:将 word1 的前 i 个字符转换成 word2 的前 j 个字符所需要的最少操作步数。

状态转移推导:

当我们考察 word1 的第 i 个字符和 word2 的第 j 个字符时,我们有三种基础操作路线:

  1. 删除 :假设我们已经把 word1 的前 i-1 个字符变成了 word2 的前 j 个字符,那么我们只需要把 word1 多出来的第 i 个字符删除 即可。代价:f[i - 1][j] + 1
  2. 插入 :假设我们已经把 word1 的前 i 个字符变成了 word2 的前 j-1 个字符,那么我们只需要再插入 一个 word2 的第 j 个字符即可。代价:f[i][j - 1] + 1
  3. 替换/跳过 :假设我们已经把 word1 的前 i-1 变成了 word2 的前 j-1
    • 如果当前字符相等(word1[i] == word2[j]),不需要操作,直接跳过。代价:f[i - 1][j - 1] + 0
    • 如果当前字符不等,我们需要做替换 操作。代价:f[i - 1][j - 1] + 1

我们取这三条路线中的最小值即可!

本解法高光点(哨兵技巧与边界处理):

代码中使用了 word1 = " " + word1; 加入空格哨兵,让真实字符从下标 1 开始,完美避免了 i-1 越界。

同时,必须正确初始化边界:

  • f[i][0] = i:把长度为 i 的字符串变成空串,必须删除 i 次。
  • f[0][j] = j:把空串变成长度为 j 的字符串,必须插入 j 次。

💻 C++ 代码实现 (标准二维 DP)

cpp 复制代码
class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();
        
        // 极客技巧:头部垫一个空格,让后续有效字符下标从 1 开始
        word1 = " " + word1;
        word2 = " " + word2;

        int f[m + 10][n + 10];
        // 初始化为一个较大值
        memset(f, 0x3f3f3f3f, sizeof f);

        // 边界初始化极其重要!
        // word1 的前 i 个字符变为空串,需要删除 i 次
        for (int i = 0; i <= m; i++) f[i][0] = i;
        // 空串变成 word2 的前 j 个字符,需要插入 j 次
        for (int j = 0; j <= n; j++) f[0][j] = j;

        // 遍历填写二维表格
        for (int i = 1; i <= m; i ++ )
        {
            for (int j = 1; j <= n; j ++ )
            {
                // 路线 1 & 2:从上方下来(删除),或从左方过来(插入)
                f[i][j] = min(f[i - 1][j], f[i][j - 1]) + 1;
                
                // 路线 3:从左上角过来(替换或直接匹配跳过)
                // 因为前面垫了空格,这里的下标直接用 i 和 j
                int cost = (word1[i] == word2[j] ? 0 : 1);
                f[i][j] = min(f[i][j], f[i - 1][j - 1] + cost);
            }
        }

        return f[m][n];
    }
};
相关推荐
chao1898444 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
沪漂阿龙4 小时前
AI大模型面试题:支持向量机是什么?间隔最大化、软间隔、核函数、LinearSVC 全面拆解
人工智能·算法·支持向量机
little~钰4 小时前
倍增算法和ST表
算法
知识领航员5 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
薛定e的猫咪5 小时前
因果推理研究方向综述笔记
人工智能·笔记·深度学习·算法
如何原谅奋力过但无声6 小时前
【灵神高频面试题合集06-08】反转链表、快慢指针(环形链表/重排链表)、前后指针(删除链表/链表去重)
数据结构·python·算法·leetcode·链表
平行侠6 小时前
037插入排序 - 整理扑克牌的算法
数据结构·算法
ECT-OS-JiuHuaShan7 小时前
彻底定理化:从量子纠缠到量子代谢
数据库·人工智能·学习·算法·生活·量子计算
jf加菲猫7 小时前
第21章 Qt WebEngine
开发语言·c++·qt·ui