极差之和
这个问题不仅考验了我们对数组操作的理解,还涉及到了数学上的极差计算和动态规划的思想。
问题描述
小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 个 1,a[1] = 3 代表数组 b 中有 3 个 2,a[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
我的解题思路:
- 构造数组
b:根据数组a构造数组b。 - 计算所有子数组的极差:对于数组
b中的每个可能的子数组,计算其最大值和最小值,然后计算极差。 - 累加所有极差:将所有子数组的极差累加起来。
- 取模:最后,对累加的极差和进行模
10^9+7操作。
代码截图:
总结:
我使用了暴力枚举所有子数组的方法,这种方法的时间复杂度是 O(n3),需要三层循环来遍历所有可能的子数组。对于较大的输入,这种方法非常慢,甚至无法在合理的时间内得到结果。
下面展示我使用豆包MarsCode AI刷题的步骤
优化思路
-
理解问题:我们需要计算所有子数组的极差之和。极差是子数组的最大值减去最小值。
-
数据结构选择:我们可以利用单调栈来优化查找子数组的最大值和最小值的过程。
-
算法步骤:
首先,构造数组 `b`。 使用单调栈来计算每个元素作为最大值和最小值时,它对极差之和的贡献。 通过单调栈,我们可以快速找到每个元素作为最大值或最小值时,它所影响的子数组的范围。
优化后的算法步骤
-
构造数组
b:- 遍历数组
a,根据a[i]的值构造数组b。
- 遍历数组
-
计算每个元素作为最大值的贡献:
- 使用单调栈来计算每个元素作为最大值和最小值时,它所影响的子数组的范围。
calculate_contribution函数用于计算每个元素的贡献,is_max参数用于区分计算最大值和最小值的贡献。
-
累加贡献并取模:
- 将所有元素作为最大值和最小值的贡献累加起来,并对 109+7 取模。
代码截图:
关键步骤
- 单调栈的实现
- 使用单调递减栈来计算每个元素作为最大值的贡献。
- 使用单调递增栈来计算每个元素作为最小值的贡献。
通过这种方法,我们可以将时间复杂度优化到 O(n),从而大大提高算法的效率。
结论:
通过这个问题,我们不仅学会了如何构造数组和计算极差,还学会了如何使用前缀和数组来优化算法。这种方法在处理大量数据时特别有效,因为它减少了重复计算,提高了算法的效率。希望这个解决方案能够帮助大家更好地理解和解决类似的问题。
针对这次的刷题我感受到豆包的高效之处,下面介绍一下我的刷题学习方法:
1. 制定刷题计划
- 学习建议:对于入门的同学,理解并掌握数据排序和索引是非常重要的。可以通过不同题目的练习,逐步积累经验,提高处理数据的能力。
- 利用豆包MarsCode的AI刷题功能,根据个人的学习进度和能力水平,智能推荐适合的题目进行练习。
- 结合个人的时间安排,制定一个明确的学习计划,每天或每周安排一定的时间用于刷题。
2. 利用豆包MarsCode AI刷题
- 利用豆包MarsCode的AI推荐系统,找到适合你当前水平的题目。
- 对于每个题目,先尝试自己解决,然后查看AI提供的思路和代码示例,逐步理解和掌握解题方法。
- 对于重要的题目,进行多遍练习,加深理解和记忆。
3. 错题的针对性学习
- 将做错的题目记录下来,分析错误原因,是理解问题、算法应用还是代码实现的问题。
- 针对错题涉及的知识点进行复习,强化薄弱环节。
- 在一段时间后重做错题,检验是否真正掌握了相关知识点。
- 对于错题,尝试找出类似的题目进行练习,做到举一反三。
工具运用
豆包MarsCode不仅是一个工具,更是现代软件开发中不可或缺的助手,它的出现推动了开发工具的技术进步,并为开发者们带来了全新的开发体验和工作方式