前言
在学习编程的过程中,刷题是提升算法与数据结构能力的重要方式。本次刷题刷到了“DNA序列编辑距离”这一题目,就以这个题目来分享我在使用豆包MarsCode AI刷题过程中的学习方法与心得,包括思路解析、知识总结、学习计划以及工具运用等方面的内容。
一、题目解析
1.问题描述
给定两个DNA序列,计算将一个受损DNA序列(dna1)转换为一个未受损序列(dna2)所需的最少编辑步骤。编辑步骤包括增加一个碱基、删除一个碱基或替换一个碱基。
2.思路分析
为解决此问题我们可以采用动态规划算法的思想,我们可以定义一个二维数组dp[m][n],其中dp[i][j]表示将前i个字符的dna1转换为前j个字符的dna2所需的最小编辑步骤。通过逐步填充这个数组,我们可以得到最终的编辑距离。
二、动态规划的步骤
1.初始化:
- 当一个序列为空时,转换所需的步骤等于另一个序列的长度。
dp[i][0] = i表示将dna1的前i个字符转换为空串需要i次删除操作。dp[0][j] = j表示将空串转换为dna2的前j个字符需要j次增加操作。
2.状态转移:
- 对于每对字符
dna1[i-1]和dna2[j-1],如果相同,则dp[i][j] = dp[i-1][j-1]。 - 如果不同,则
dp[i][j]取三种操作中的最小值:删除、增加和替换。
3.返回结果:
- 最终结果为
dp[m][n],其中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
for j in range(n + 1):
dp[0][j]=j
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]
if __name__ == "__main__":
# You can add more test cases here
print(solution("AGCTTAGC", "AGCTAGCT") == 2 )
print(solution("AGCCGAGC", "GCTAGCT") == 4)
四、知识总结
在使用豆包MarsCode AI刷题的过程中,对于此题,我总结了以下几个关键知识点:
- 动态规划的思想: 动态规划是一种通过将复杂问题分解为更简单的子问题来解决问题的方法。在本题中,通过构建
dp数组,找出状态转移方程来存储中间结果,从而避免重复计算。 - 状态转移方程: 状态转移方程是动态规划的核心。在本题中,通过比较当前字符来决定是继续保持、删除、增加还是替换,从而选择最优解。
- 边界条件的设置: 在动态规划中,合理设置边界条件是非常重要的。通过初始化
dp数组的边界,可以确保后续计算的正确性。
五、学习计划
结合豆包MarsCode AI的刷题功能,我制定了以下学习计划:
- 每日刷题: 每天至少选择1-2道题目进行练习,保持持续的学习状态。可以根据难度逐步增加题目的复杂性。
- AI伴学: 对于思路难以想到的题目,结合豆包AI的问答功能寻找做题的思路,记录下来并进行深入分析,了解使用的算法思想,在算法思想的学习和算法的实现中逐渐掌握相关算法的核心思想以及算法的使用。
- 定期总结: 每天对所学知识进行总结,梳理算法核心概念,将使用相同的算法的题目记录整理下来。
六、工具运用
在学习过程中,我将豆包MarsCode AI的刷题功能与其他学习资源结合,取得了良好的效果:
- 结合视频教程: 在遇到难以理解的算法时,观看相关的视频教程,帮助理解复杂的算法。
- 使用笔记工具: 记录每道题目的解题思路和代码实现,形成做题记录,便于日后查阅。
- 结合算法书籍:参考算法书籍的算法实现过程来逐步完善自己的代码,积累从算法思想到编程实现的经验。
小结
在“DNA序列编辑距离”这一题目的练习过程中,我不仅掌握了动态规划的基本思想,还提升了自己的编程能力。在未来的学习中,我将继续利用豆包MarsCode AI的刷题功能提升解决问题的能力。希望本文能为其他入门同学提供一些实用的学习建议。