如何解决“小B的极差之和”问题 题目解析 | 豆包MarsCode AI刷题

79 阅读5分钟

极差之和

这个问题不仅考验了我们对数组操作的理解,还涉及到了数学上的极差计算和动态规划的思想。

问题描述

小B拥有一个数组 a,她使用这个数组构造了一个新数组 b。其中,a[i] 表示在新数组 b 中有 a[i]i+1。例如,若 a = [2, 3, 1],那么新数组 b = [1, 1, 2, 2, 2, 3],因为 a[0] = 2 代表数组 b 中有 2 个 1a[1] = 3 代表数组 b 中有 3 个 2a[2] = 1 代表数组 b 中有 1 个 3

现在,你需要帮助小B求出 b 数组中所有连续子数组的极差之和。由于答案可能非常大,请对 109+7109+7 取模。

数组的极差定义为子数组的最大值减去最小值。

测试样例

样例1:

输入:n = 2,a = [2, 1]
输出:2

样例2:

输入:n = 3,a = [1, 2, 1]
输出:6

样例3:

输入:n = 4,a = [2, 3, 1, 1]
输出:26

我的解题思路:

  1. 构造数组 b:根据数组 a 构造数组 b
  2. 计算所有子数组的极差:对于数组 b 中的每个可能的子数组,计算其最大值和最小值,然后计算极差。
  3. 累加所有极差:将所有子数组的极差累加起来。
  4. 取模:最后,对累加的极差和进行模 10^9+7 操作。

代码截图:

image.png

image.png

总结:

我使用了暴力枚举所有子数组的方法,这种方法的时间复杂度是 O(n3),需要三层循环来遍历所有可能的子数组。对于较大的输入,这种方法非常慢,甚至无法在合理的时间内得到结果。


下面展示我使用豆包MarsCode AI刷题的步骤

优化思路

  1. 理解问题:我们需要计算所有子数组的极差之和。极差是子数组的最大值减去最小值。

  2. 数据结构选择:我们可以利用单调栈来优化查找子数组的最大值和最小值的过程。

  3. 算法步骤

     首先,构造数组 `b`。
     使用单调栈来计算每个元素作为最大值和最小值时,它对极差之和的贡献。
     通过单调栈,我们可以快速找到每个元素作为最大值或最小值时,它所影响的子数组的范围。
    

优化后的算法步骤

  1. 构造数组 b

    • 遍历数组 a,根据 a[i] 的值构造数组 b
  2. 计算每个元素作为最大值的贡献

    • 使用单调栈来计算每个元素作为最大值和最小值时,它所影响的子数组的范围。
    • calculate_contribution 函数用于计算每个元素的贡献,is_max 参数用于区分计算最大值和最小值的贡献。
  3. 累加贡献并取模

    • 将所有元素作为最大值和最小值的贡献累加起来,并对 109+7 取模。

代码截图:

image.png image.png

关键步骤

  • 单调栈的实现
    • 使用单调递减栈来计算每个元素作为最大值的贡献。
    • 使用单调递增栈来计算每个元素作为最小值的贡献。

通过这种方法,我们可以将时间复杂度优化到 O(n),从而大大提高算法的效率。

结论:

通过这个问题,我们不仅学会了如何构造数组和计算极差,还学会了如何使用前缀和数组来优化算法。这种方法在处理大量数据时特别有效,因为它减少了重复计算,提高了算法的效率。希望这个解决方案能够帮助大家更好地理解和解决类似的问题。


针对这次的刷题我感受到豆包的高效之处,下面介绍一下我的刷题学习方法:

1. 制定刷题计划

  • 学习建议:对于入门的同学,理解并掌握数据排序和索引是非常重要的。可以通过不同题目的练习,逐步积累经验,提高处理数据的能力。
  • 利用豆包MarsCode的AI刷题功能,根据个人的学习进度和能力水平,智能推荐适合的题目进行练习。
  • 结合个人的时间安排,制定一个明确的学习计划,每天或每周安排一定的时间用于刷题。

2. 利用豆包MarsCode AI刷题

  • 利用豆包MarsCode的AI推荐系统,找到适合你当前水平的题目。
  • 对于每个题目,先尝试自己解决,然后查看AI提供的思路和代码示例,逐步理解和掌握解题方法。
  • 对于重要的题目,进行多遍练习,加深理解和记忆。

3. 错题的针对性学习

  • 将做错的题目记录下来,分析错误原因,是理解问题、算法应用还是代码实现的问题。
  • 针对错题涉及的知识点进行复习,强化薄弱环节。
  • 在一段时间后重做错题,检验是否真正掌握了相关知识点。
  • 对于错题,尝试找出类似的题目进行练习,做到举一反三。

工具运用

豆包MarsCode不仅是一个工具,更是现代软件开发中不可或缺的助手,它的出现推动了开发工具的技术进步,并为开发者们带来了全新的开发体验和工作方式