题目解析 问题描述 这个题目要求计算两个DNA序列之间的编辑距离(Levenshtein Distance)。编辑距离是通过插入、删除和替换字符所需的最小操作数来衡量两个字符串之间的差异。 解题思路
1.动态规划:使用动态规划(Dynamic Programming)来求解编辑距离。我们构建一个二维数组 dp,其中 dp[i][j] 表示将前 i 个字符的 dna1 转换为前 j 个字符的 dna2 所需的最小操作数。 2.初始化:
3.dp[i][0] 表示将 dna1 的前 i 个字符转换为空字符串的操作数,即需要进行 i 次删除操作。 4.dp[0][j] 表示将空字符串转换为 dna2 的前 j 个字符的操作数,即需要进行 j 次插入操作。
5.状态转移:
6.如果 dna1[i-1] 等于 dna2[j-1],则 dp[i][j] = dp[i-1][j-1](无需操作)。 7.如果不相等,考虑三种操作:删除、插入和替换,选择最小值: 8.删除:dp[i-1][j] + 1 9.插入:dp[i][j-1] + 1 10.替换:dp[i-1][j-1] + 1
11.最终结果:dp[m][n] 就是 dna1 和 dna2 之间的编辑距离。
代码详解 def solution(dna1, dna2): m = len(dna1) n = len(dna2)
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(m + 1):
dp[i][0] = i # 从dna1到空字符串的操作数
for j in range(n + 1):
dp[0][j] = j # 从空字符串到dna2的操作数
for i in range(1, m + 1):
for j in range(1, n + 1):
if dna1[i - 1] == dna2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] # 字符匹配,无需操作
else:
dp[i][j] = min(dp[i - 1][j] + 1, # 删除
dp[i][j - 1] + 1, # 插入
dp[i - 1][j - 1] + 1) # 替换
return dp[m][n] # 返回编辑距离
测试用例
12.solution("AGCTTAGC", "AGCTAGCT") 应返回 2 13.solution("AGCCGAGC", "GCTAGCT") 应返回 4
知识总结 在使用豆包MarsCode AI 刷题的过程中,我总结了一些重要的知识点:
14.动态规划的应用:动态规划常用于解决最优化问题,特别是涉及到决策过程的问题,例如最小编辑距离、最长公共子序列等。 15.状态转移方程的构建:建立DP表时,必须清晰地定义状态及其转移方式,这是解决动态规划问题的关键。 16.边界条件的重要性:初始化DP表的第一行和第一列非常重要,能够帮助正确计算后续的状态。
学习建议
17.多做练习:通过不断实践,巩固对动态规划的理解,尝试不同类型的题目。 18.理解而不是记忆:理解动态规划的思路比单纯记忆公式更为重要。
学习计划 结合豆包MarsCode AI 刷题功能,我制定了以下学习计划:
19.制定每日刷题计划:
20.每天固定时间进行1-2道动态规划相关题目,确保涵盖基础和进阶难度。 21.使用豆包的题库,挑选不同类型的题目,增强适应性。
22.错题分析:
23.每周回顾自己的错题,分析错误原因,重新理解相关的知识点。 24.针对错题制定复习计划,确保能熟练掌握。
工具运用 在学习过程中,将AI刷题功能与其他学习资源结合,可以取得更好的效果:
25.结合参考书籍和在线课程:遇到难题时,参考相关书籍中的解释和例题,或者查阅在线课程来加深理解。 26.利用社区和论坛:在豆包MarsCode AI的社区中提问,或在其他编程论坛上讨论难点,获得不同的解法和思路。 27.定期总结和反思:定期对自己的学习进度和掌握程度进行总结,调整学习策略,确保不断提高。
通过这样的学习计划和资源运用,可以有效提升自己的编程能力,特别是在算法和数据结构方面。