news 2026/4/16 12:15:24

动态规划解法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
动态规划解法

一、动态规划解编辑距离的核心原理

编辑距离(Levenshtein 距离)的动态规划解法核心是用二维数组存储子问题的解,避免递归的重复计算,其核心逻辑基于:

  • 定义dp[i][j]:表示将word1的前i个字符转换成word2的前j个字符所需的最少操作次数
  • 边界条件:
    • dp[i][0] = i:把word1i个字符转成空字符串,需要删除i次;
    • dp[0][j] = j:把空字符串转成word2j个字符,需要插入j次。
  • 状态转移:
    • 如果word1[i-1] == word2[j-1](当前字符相等):无需操作,dp[i][j] = dp[i-1][j-1]
    • 如果word1[i-1] != word2[j-1](当前字符不等):取「删除、插入、替换」三种操作的最小值 + 1,即:dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1

二、动态规划解法代码逐行解析

下面针对dpEditDistance函数逐行拆解,帮你理解每一步的作用:

int dpEditDistance(string& word1, string& word2) { // 1. 获取两个字符串的长度(m=word1长度,n=word2长度) int m = word1.size(), n = word2.size(); // 2. 定义DP表:静态二维数组,大小(MAX_LEN+1)x(MAX_LEN+1) // 为什么+1?因为dp[i][j]对应前i/j个字符,需要包含i=0/j=0的边界情况 int dp[MAX_LEN + 1][MAX_LEN + 1]; // 3. 初始化边界条件(核心!) // 边界1:word2为空,word1前i个字符转空需要删除i次 for (int i = 0; i <= m; ++i) dp[i][0] = i; // 边界2:word1为空,空字符串转word2前j个字符需要插入j次 for (int j = 0; j <= n; ++j) dp[0][j] = j; // 4. 填充DP表(核心状态转移) // 遍历word1的每个字符(i从1到m,对应前i个字符) for (int i = 1; i <= m; ++i) { // 遍历word2的每个字符(j从1到n,对应前j个字符) for (int j = 1; j <= n; ++j) { // 情况1:当前字符相等(word1[i-1]是第i个字符,因为数组从0开始) if (word1[i - 1] == word2[j - 1]) { // 无需操作,直接继承前i-1和j-1的结果 dp[i][j] = dp[i - 1][j - 1]; } else { // 情况2:当前字符不等,取三种操作的最小值+1 // dp[i-1][j]:删除word1第i个字符(操作数+1) // dp[i][j-1]:给word1插入word2第j个字符(操作数+1) // dp[i-1][j-1]:替换word1第i个字符为word2第j个字符(操作数+1) dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1; } } } // 5. 返回最终结果:word1全量转word2全量的最少操作次数 return dp[m][n]; }

三、实际执行示例(以 "horse"→"ros" 为例)

我们用代码中的测试用例word1="horse"(m=5)、word2="ros"(n=3),看 DP 表的填充过程:

步骤 1:初始化边界
i\j0 (空)1 (r)2 (ro)3 (ros)
00123
11
22
33
44
55
步骤 2:填充 DP 表(关键节点)
  • i=1 (h)j=1 (r)h≠rmin(dp[0][1], dp[1][0], dp[0][0])+1 = min(1,1,0)+1=1dp[1][1]=1
  • i=3 (r)j=1 (r)r=rdp[3][1] = dp[2][0] = 2
  • i=5 (e)j=3 (s)e≠smin(dp[4][3], dp[5][2], dp[4][2])+1→ 最终dp[5][3]=3(和代码输出一致)。

最终结果dp[5][3]=3,表示 "horse" 转 "ros" 最少需要 3 次操作(删除 h、删除 e、替换 s→e,或其他等价操作)。

四、动态规划解法的优化点(可选)

你提供的代码用了静态二维数组,虽然简单但有优化空间,适合新手进阶:

空间优化(一维数组):观察状态转移可知,dp[i][j]只依赖dp[i-1][j]dp[i][j-1]dp[i-1][j-1],因此可以用一维数组代替二维数组,空间复杂度从O(m∗n)降到O(min(m,n)):

int dpEditDistanceOpt(string& word1, string& word2) { int m = word1.size(), n = word2.size(); // 用一维数组,长度为较短字符串+1 if (m < n) return dpEditDistanceOpt(word2, word1); int dp[n + 1]; // 初始化边界 for (int j = 0; j <= n; ++j) dp[j] = j; // 填充一维DP for (int i = 1; i <= m; ++i) { int prev = dp[0]; // 保存dp[i-1][j-1]的值 dp[0] = i; // 对应dp[i][0] = i for (int j = 1; j <= n; ++j) { int temp = dp[j]; // 保存当前dp[j](即dp[i-1][j]) if (word1[i-1] == word2[j-1]) { dp[j] = prev; } else { dp[j] = min(min(dp[j], dp[j-1]), prev) + 1; } prev = temp; // 更新prev为下一轮的dp[i-1][j-1] } } return dp[n]; }

总结

动态规划解法的核心要点:

  1. dp[i][j]定义为「word1 前 i 个字符转 word2 前 j 个字符的最少操作数」,是整个解法的基础;

  2. 边界条件处理空字符串的特殊情况,状态转移覆盖「删除、插入、替换」三种操作;
  3. 相比纯递归,动态规划通过迭代填充 DP 表,时间复杂度O(m∗n),无重复计算;相比记忆化递归,无需递归调用栈,效率更高。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 9:50:03

大模型RAG检索增强生成技术全解析:收藏级教程,小白也能懂!

RAG&#xff08;检索增强生成&#xff09;技术通过集成外部知识库&#xff0c;有效解决大模型在面对幻觉、最新知识及复杂任务时的不足。其工作流程包括&#xff1a;用户提问→理解问题意图→检索知识库相关文档→整合文档形成提示词→大模型生成精确答案。本文全面介绍了RAG方…

作者头像 李华
网站建设 2026/4/10 15:55:39

AI重塑论文写作:10款工具完成数学建模复现到智能排版全流程

还在为数学建模论文的复现和排版发愁&#xff1f;时间紧迫却无从下手&#xff1f;AI工具或许能成为你的高效助手。本文精选并评测10款热门AI论文写作工具&#xff0c;助你快速找到最适合的解决方案&#xff0c;轻松提升论文质量与效率。aibiye&#xff1a;专注于语法润色与结构…

作者头像 李华
网站建设 2026/4/13 15:34:01

手把手带你读Corespec:逻辑链路控制与适配协议(L2CAP) 上

一、介绍 This section of the Bluetooth Specification defines the Logical Link Control and Adaptation Layer Protocol, referred to as L2CAP. L2CAP provides connection-oriented and connectionless data services to upper layer protocols with protocol multiplex…

作者头像 李华
网站建设 2026/4/7 12:09:11

北京做种植牙一颗要多少钱

北京种植牙价格解析&#xff1a;从技术到成本的全维度洞察引言&#xff1a;种植牙为何成为缺牙修复首选&#xff1f;随着口腔医学技术的进步&#xff0c;种植牙因其接近天然牙的功能与美观性&#xff0c;逐渐成为缺牙修复的主流方案。然而&#xff0c;北京作为医疗资源集中的一…

作者头像 李华
网站建设 2026/3/28 6:50:22

Azure RTOS ThreadX 是什么?

Azure RTOS ThreadX 是什么&#xff1f;Azure RTOS ThreadX 是一款高性能、高可靠性的实时操作系统&#xff0c;最初由 Express Logic 公司开发&#xff0c;现已成为 Microsoft Azure RTOS 套件的核心组件。它专为深度嵌入式、资源受限且要求高确定性的应用场景而设计。 以下是…

作者头像 李华
网站建设 2026/4/16 9:05:09

UVa 11166 Power Signs

题目描述 给定一个正整数 nnn &#xff0c;它的二进制表示为不含前导零的二进制字符串。我们需要将 nnn 表示为带符号的二进制表示&#xff08; signedbinaryrepresentation\texttt{signed binary representation}signed binary representation &#xff09;&#xff0c;即&am…

作者头像 李华