在这篇笔记中,我将通过解析一个典型的编程题目,分享我的学习心得与解题思路。这道题目要求我们从一组观光景点中,选择一对景点,使得它们的组合得分最高。得分的计算公式为:values[i] + values[j] + i - j,其中 values[i] 和 values[j] 分别是第 i 和第 j 个景点的评分,i 和 j 的差值代表这两个景点之间的距离。任务是求解出在何种情况下能够获得最高的得分。
问题分析
给定一个整数数组 values,其中每个元素表示一个景点的评分,问题的核心是要找出一个最优的景点组合 (i, j),使得得分:
[ score(i, j) = values[i] + values[j] + i - j ]
其中,i < j。这道题的难点在于如何有效地求解这个最大得分问题,并且保证时间复杂度不超过 O(n^2),否则对于大规模的输入会超时。
解题思路
-
公式简化与拆解: 我们可以对
score(i, j)进行分析,拆解成两部分:[ score(i, j) = (values[i] + i) + (values[j] - j) ]
通过这样的拆解,我们可以看到,问题转化为两个部分的和:
values[i] + i:这部分对于每个i都是一个固定的值。values[j] - j:这部分对于每个j都是一个固定的值。
这样,我们就能在遍历时分别计算每个
i的值和每个j的值,而不需要进行重复的嵌套循环。 -
优化思路: 我们可以通过维护一个变量
maxv,来存储values[i] + i的最大值。然后在遍历每个景点时,利用当前景点的评分values[j] - j来计算得分。最终的最大得分就是maxv和values[j] - j之和的最大值。
代码详解
#include <bits/stdc++.h>
using namespace std;
int solution(vector<int> values) {
if(values.size() == 1) return 0; // 如果只有一个景点,无法组成组合,直接返回 0
int maxv = 0, res = 0; // maxv 用于存储 values[i] + i 的最大值,res 用于存储最大得分
for(int i = 0; i < values.size(); i++) {
res = max(res, values[i] - i + maxv); // 计算当前景点的得分,更新最大得分
maxv = max(maxv, values[i] + i); // 更新 maxv,保证它是 values[i] + i 的最大值
}
return res; // 返回最大得分
}
int main() {
cout << (solution({8, 3, 5, 5, 6}) == 11) << endl; // 测试用例 1
cout << (solution({10, 4, 8, 7}) == 16) << endl; // 测试用例 2
cout << (solution({1, 2, 3, 4, 5}) == 8) << endl; // 测试用例 3
return 0;
}
代码解析
-
初始化:
maxv记录当前已遍历过的元素中,values[i] + i的最大值。最初设为0。res记录最大得分,最初也设为0。
-
遍历数组:
- 对于每个
i,我们计算values[i] - i + maxv,表示当前景点与前面景点的组合得分。 - 更新
maxv,使其保留最大值values[i] + i。
- 对于每个
-
返回结果:
- 最后,
res就是我们所求的最大得分。
- 最后,
时间复杂度与空间复杂度
- 时间复杂度:
O(n)。我们只需要遍历一次数组,因此时间复杂度是线性的。 - 空间复杂度:
O(1)。只用了常数空间来存储maxv和res,没有使用额外的空间。
知识总结
在解这类题目时,关键是找到合适的数学表达式,将复杂的问题简化为更易处理的形式。在本题中,通过拆解公式并引入辅助变量 maxv,我们可以避免双重循环,从而大大提高效率。这种优化技巧对于大规模数据的处理尤为重要。
对入门同学的学习建议
-
理解题目中的数学公式:解题时,要学会从公式中提炼出可以优化的部分。经常会遇到这种可以通过数学转换来简化计算的情况。
-
关注优化空间:有些题目看似需要两层循环,但实际通过巧妙的数学推导,可以将其降低到一层循环,从而提升效率。
-
边学边练:在解题过程中,遇到不懂的部分,可以通过查阅相关资料或参考他人的解法,积累解题经验。建议多做一些类似的题目,提升自己的算法思维。
高效学习方法
在使用 豆包MarsCode AI刷题 的过程中,我总结了一些高效学习的方法:
- 制定刷题计划:每天设置固定时间,确保持续不断地练习。每次练习后,回顾自己的解法,思考是否有优化空间。
- 利用错题进行针对性学习:错题是宝贵的学习资源,应该总结出错因并针对性复习。可以将错题整理成笔记,随时回顾。
- 结合学习资源:AI刷题功能可以与其他学习资源结合使用,例如看视频教程、阅读算法书籍等,这样可以加深对知识点的理解。
通过不断练习和思考,我们可以更好地掌握算法技巧,并提高编程能力。
结语
这道题的解法充分体现了算法优化的精髓,尤其是在时间复杂度方面的优化。希望通过这篇笔记,能帮助大家更好地理解算法思路与解题技巧。同时,也希望能为正在刷题的同学们提供一些有益的学习经验。