青训营X豆包MarsCode技术训练营伴学笔记|实践记录以及工具使用(3)|豆包MarsCode AI刷题

67 阅读6分钟

AI刷题的优势

豆包MarsCode AI刷题工具的一些核心优势:

  1. 智能测试与动态优化
    AI 会根据题目自动生成多种测试用例,包括边界情况和随机数据,帮助发现潜在的漏洞。同时,它还能动态评估代码运行效率,给出性能优化建议。
  2. 多解法对比与学习
    平台提供的多解法对比功能,让用户不仅仅停留在“解对题”的层面,还能通过多角度解法提高编程思维能力。
  3. 实时反馈与代码分析
    AI 工具会实时反馈错误位置,详细分析代码逻辑问题,帮助用户理解错误原因并快速修复。

今天我们以81.古生物DNA序列血缘分析为例子来探讨豆包MarsCode AI工具的优势

问题描述

小U是一位古生物学家,正在研究不同物种之间的血缘关系。为了分析两种古生物的血缘远近,她需要比较它们的DNA序列。DNA由四种核苷酸A、C、G、T组成,并且可能通过三种方式发生变异:添加一个核苷酸、删除一个核苷酸或替换一个核苷酸。小U认为两条DNA序列之间的最小变异次数可以反映它们之间的血缘关系:变异次数越少,血缘关系越近。

你的任务是编写一个算法,帮助小U计算两条DNA序列之间所需的最小变异次数。

  • dna1: 第一条DNA序列。
  • dna2: 第二条DNA序列。

测试样例

样例1:

输入:dna1 = "AGT",dna2 = "AGCT"
输出:1

样例2:

输入:dna1 = "AACCGGTT",dna2 = "AACCTTGG"
输出:4

样例3:

输入:dna1 = "ACGT",dna2 = "TGC"
输出:3

样例4:

输入:dna1 = "A",dna2 = "T"
输出:1

样例5:

输入:dna1 = "GGGG",dna2 = "TTTT"
输出:4

以下是豆包给的思路提示 要解决这个问题,我们可以使用动态规划(Dynamic Programming)来计算两条DNA序列之间的最小变异次数。以下是解题思路:

问题理解

我们需要计算两条DNA序列之间的最小变异次数,变异包括三种操作:插入、删除和替换。这个问题可以转化为计算两个字符串之间的编辑距离(Edit Distance)。

数据结构选择

我们选择一个二维数组 dp 来存储中间结果。dp[i][j] 表示 dna1 的前 i 个字符和 dna2 的前 j 个字符之间的最小变异次数。

算法步骤

  1. 初始化

    • 如果 dna1 为空,那么 dp[0][j] 就是 j,因为需要 j 次插入操作。
    • 如果 dna2 为空,那么 dp[i][0] 就是 i,因为需要 i 次删除操作。
  2. 状态转移

    • 如果 dna1[i-1] == dna2[j-1],那么 dp[i][j] = dp[i-1][j-1],因为不需要任何操作。

    • 如果 dna1[i-1] != dna2[j-1],那么 dp[i][j] 可以通过以下三种操作的最小值得到:

      • 替换操作:dp[i-1][j-1] + 1
      • 插入操作:dp[i][j-1] + 1
      • 删除操作:dp[i-1][j] + 1
  3. 最终结果

    • dp[m][n] 就是 dna1dna2 之间的最小变异次数,其中 mn 分别是 dna1dna2 的长度。

通过上述步骤,我们可以逐步填充 dp 表,最终得到所需的结果。

通过之前的代码学习加上豆包给的思路提示我们很快就能写出初步代码

def solution(dna1, dna2):

    m, n = len(dna1), 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

   

    # 填充dp表

    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] + 1, dp[i][j-1] + 1, dp[i-1][j] + 1)

   

    return dp[m][n]

if __name__ == "__main__":

    #  You can add more test cases here

    print(solution("AGT", "AGCT") == 1)

    print(solution("", "ACGT") == 4)

    print(solution("GCTAGCAT", "ACGT") == 5)

image.png 运气很好我们第一次就提交成功了。 但是代码能否有提升空间或者优化的地方呢。一般优化就是从时间性能和空间复杂度出发。但对新手小白来说这是很难想的。但豆包MarsCode AI很贴心的给我们进行联想功能。仿佛已经提前预判你的问题一般给你提前准备好了问题答案。

image.png

这就是豆包给出的减小空间复杂度的方案

def solution(dna1, dna2):
    m, n = len(dna1), len(dna2)
    
    # 初始化 prev 数组
    prev = [j for j in range(n + 1)]
    curr = [0] * (n + 1)
    
    for i in range(1, m + 1):
        # 初始化 curr 数组的第一个元素
        curr[0] = i
        
        for j in range(1, n + 1):
            if dna1[i-1] == dna2[j-1]:
                curr[j] = prev[j-1]
            else:
                curr[j] = min(prev[j-1], curr[j-1], prev[j]) + 1
        
        # 交换 prev 和 curr 数组
        prev, curr = curr, prev
    
    return prev[n]

每次写代码都会贴心的给你代码解读。对于新手非常友好

解释

  • prev 数组初始化为 [0, 1, 2, ..., n],表示 dna1 为空时的编辑距离。
  • curr 数组用于存储当前行的状态。
  • 在每一行的计算结束后,交换 prevcurr 数组,以便在下一行使用。

通过这种方式,我们将空间复杂度从 O(m * n) 降低到 O(n),其中 mn 分别是 dna1dna2 的长度。

这样我们对这道题目就更增加了理解。代码能力和思维能力都被拓宽了。

总结

使用心得:豆包MarsCode AI刷题工具

在使用豆包MarsCode AI刷题工具的过程中,我体验到了现代AI技术在学习领域的强大助力。尤其是在精选真题和个性化题目推荐功能的助力下,我的学习效率和效果都有了显著的提升。

AI刷题工具的优势

在我的刷题实践中,豆包MarsCode AI工具通过其智能的题目推荐和便捷的题目解析,为我提供了诸多优势。其云端编辑器功能也相当便捷,无需本地配置环境、随时随地即可练习。

  1. 学习过程

    • 通过几周的练习,我发现自己的解题速度和准确率都有了明显提升。尤其是在动态规划题目方面,MarsCode的分步解析帮助我理解了状态转移的细节与技巧,避免了很多陷阱。
    • 系统根据我的进步情况,不断为我调整题目挑战的难度,使得我始终保持在一个可控但有效的学习状态,提升自信心。
  2. 总结与反思

    • 豆包MarsCode的AI功能有效地帮助我克服了学习中的瓶颈,通过智能推荐和优质解析,提高了我的学习效率。
    • 这种结合智能化和个性化的学习工具,不仅帮助我在考试中取得了优异成绩,也培养了我解决问题时应对不同挑战的策略。

总之,豆包MarsCode AI刷题工具通过精选真题与个性化推荐功能,帮助我高效地掌握了复杂的算法知识,也提升了我的自学能力,是我学习过程中的得力助手。