学习方法与心得1 | 豆包MarsCode AI刷题

105 阅读6分钟

学习方法与心得

在学习算法和编程的过程中,刷题是一个不可或缺的部分,尤其是当学习如何解决不同类型的问题时,刷题能帮助我们加深理解,掌握算法思维。通过使用豆包MarsCode AI刷题平台,我不仅在刷题中巩固了编程技能,还通过每道题的解析积累了很多新的知识点。在这篇学习笔记中,我将分享我在使用MarsCode AI刷题时的学习心得,并且详细解析一道豆包MarsCode AI 刷题(代码练习)题库的题目。

题目解析

问题描述

题目要求我们找到一个正方形切割区域,使得切割后的两个部分——小R和小S分配的美味度之和尽量接近。给定一个大小为 n 行 m 列的矩阵,每个元素代表该位置的美味度,我们需要计算如何切割出一个正方形区域,使得该区域与剩余部分的美味度差最小。问题的关键在于如何高效地计算子矩形区域的美味度和,避免重复计算。

解题思路

这个问题的核心思想是:如何高效地计算一个矩阵中任意子矩形(特别是正方形)的和。直接暴力计算每个可能的正方形区域的和,时间复杂度过高,因此我们需要使用 前缀和(Prefix Sum) 来优化这个过程。

前缀和的构建: 前缀和是一种通过累计部分和的方式,快速计算矩阵中任意子矩形和的方法。前缀和矩阵 prefix_sum[i][j] 存储的是从 (0,0) 到 (i-1,j-1) 矩阵区域的所有元素的和。通过前缀和,我们可以在常数时间内计算任意子矩形的和。

具体计算公式为:

prefix_sum[i][j] = a[i-1][j-1] + prefix_sum[i-1][j] + prefix_sum[i][j-1] - prefix_sum[i-1][j-1]

利用这个前缀和数组,我们可以在 O(1) 时间内获取任意子矩形的和,因此可以高效地遍历所有正方形区域,计算出其美味度之和。

解题步骤     构建前缀和数组: 首先通过两重循环,计算出矩阵的前缀和数组 prefix_sum。     遍历所有可能的正方形: 对于每个可能的正方形区域,计算其美味度和 s1,然后用总美味度减去 s1 得到 s2,计算 |s1 - s2| 的值,更新最小值。     返回结果: 最终输出最小的 |s1 - s2|。

代码实现

def solution(n: int, m: int, a: list) -> int:

    # 计算前缀和数组

    prefix_sum = [[0] * (m + 1) for _ in range(n + 1)]

    for i in range(1, n + 1):

        for j in range(1, m + 1):

            prefix_sum[i][j] = a[i-1][j-1] + prefix_sum[i-1][j] + prefix_sum[i][j-1] - prefix_sum[i-1][j-1]

    min_diff = float('inf')

    # 遍历所有可能的正方形边长

    for size in range(1, min(n, m) + 1):

        for i in range(n - size + 1):

            for j in range(m - size + 1):

                # 计算正方形的美味度之和 s1

                s1 = prefix_sum[i+size][j+size] - prefix_sum[i][j+size] - prefix_sum[i+size][j] + prefix_sum[i][j]

                # 计算剩余部分的美味度之和 s2

                total_sum = prefix_sum[n][m]

                s2 = total_sum - s1

                # 更新最小差值

                min_diff = min(min_diff, abs(s1 - s2))

    return min_diff

代码解释

    前缀和计算: 使用 prefix_sum[i][j] 存储从 (0, 0) 到 (i-1, j-1) 区域的美味度和。每次更新 prefix_sum[i][j] 时,使用了动态规划的思想,利用先前计算的结果来更新当前值。

    遍历正方形区域: 我们通过三个循环,遍历了所有可能的正方形区域:size 表示正方形的边长,i 和 j 是正方形的左上角坐标。

    计算美味度和: 使用前缀和公式来快速计算出正方形区域的美味度和 s1,并通过总美味度减去 s1 得到剩余区域的美味度和 s2,进而计算 |s1 - s2| 的值。

    最小差值更新: 每次计算出一个正方形区域的美味度差,我们都会更新最小差值 min_diff,最终返回这个最小差值。

知识总结

  1. 前缀和技术

前缀和是一种非常高效的技术,能够让我们在常数时间内计算任意矩形区域的和。这在处理二维数组问题时尤其重要。通过预先计算所有元素的累加和,我们避免了重复计算,从而显著提高了时间效率。

  1. 动态规划思想

虽然本题的核心是前缀和技术,但通过动态规划的思想,我们可以优化计算过程。通过保存已经计算的结果,我们能够减少不必要的重复计算。

  1. 时间复杂度优化

在没有前缀和的情况下,我们每次计算子矩形的和需要遍历整个区域,这样的时间复杂度为 O(n^2 * m^2),而使用前缀和后,时间复杂度优化为 O(n * m),使得问题能够在较大的输入下也能有效解决。

学习计划

  1. 合理制定刷题计划

    刷题时,我建议大家按照难度逐步提升,从简单的题目开始,逐步过渡到中等难度和高难度的题目。在刷题的过程中,不要急于解决所有题目,而是要专注于理解每个问题背后的核心思想。

  2. 注重错题分析

    对于每一道题目,做错的题目要特别注意。通过分析错题,查找自己理解不清晰的地方,可以加深对知识点的理解。我通常会在MarsCode AI的错题本中记录下错误原因,并复习相关知识点。

  3. 提高问题解决的思维方式

    我会把每道题目分为三个阶段:理解问题,设计解决方案,写代码实现。理解问题时,仔细分析题目给定的输入和要求,设计解决方案时,通过思维导图或者简短的笔记记录关键步骤,最后写代码实现并调试。

工具运用

  1. MarsCode AI 刷题功能

    MarsCode AI不仅提供了丰富的题库和自动评测系统,还能根据个人刷题历史生成针对性的学习推荐,帮助我发现知识盲点。每次遇到困难时,我都可以利用AI的提示功能来获得思路和解题技巧,从而提高解题效率。

  2. 与其他学习资源结合

    除了MarsCode AI,我还会结合其他学习资源,如算法书籍、在线教学视频等进行学习。通过阅读理论书籍,我能够理解更多的算法和数据结构原理,而通过实际刷题,我能够将理论应用到实际问题中,巩固学习成果。

    刷题不仅仅是解决一个个问题,更是培养自己的算法思维和编程能力的过程。通过使用MarsCode AI刷题,我不仅提高了解决问题的速度,还学会了如何系统地分析和解决问题。在刷题过程中,我不断积累经验,掌握了更多的技巧,这些经验对我今后的学习和工作都将产生深远的影响。