青训营X豆包MarsCode 技术训练营 | 豆包MarsCode AI 刷题

34 阅读3分钟

问题描述

每个景点都有一个评分,保存在数组 values 中,其中 values[i] 表示第 i 个观光景点的评分。同时,景点之间的距离由它们的下标差 j - i 表示。一对景点 (i < j) 的观光组合得分为 values[i] + values[j] + i - j,也就是两者评分之和减去它们之间的距离,在哪种情况下能够获得观光景点组合的最高得分。

测试样例

样例1:

输入:values = [8, 3, 5, 5, 6]
输出:11

样例2:

输入:values = [10, 4, 8, 7]
输出:16

样例3:

输入:values = [1, 2, 3, 4, 5]
输出:8

作为一名机械专业的学生,这次AI刷题最吸引我的特定功能亮点无疑是思路提示,例如在解答这题时,我起初是认为空间复杂度是O(n)然后写了半天发现没有结果出来,然后我就发现旁边的AI刷题有思路提示,发现时间复杂度为 O(n),空间复杂度为 O(1)。

解题思路转换

然后某天在学习代码知识时看到这样的例子然后感觉和该题目AI的思路提示相似然后回来做才解开的,于是我们的解题思路可以这样看

假设你有一个装满数字的盒子,你想从盒子里挑出两个不同的数字,并且按照一个特殊的规则计算这两个数字的分数:

规则:

  1. 把两个数字加起来。
  2. 把第一个数字的位置(索引)减去第二个数字的位置(索引)。  索引是从0开始计数的,例如第一个数字的索引是0,第二个数字的索引是1,以此类推。
  3. 把步骤1和步骤2的结果加起来,就是最终的分数。

程序的目标是找到能得到最高分数的那对数字。

我先假设了这样的一个例子:values = [8, 3, 5, 5, 6]

  • (8, 3): 8 + 3 + 0 - 1 = 10
  • (8, 5): 8 + 5 + 0 - 2 = 11
  • (8, 5): 8 + 5 + 0 - 3 = 10
  • (8, 6): 8 + 6 + 0 - 4 = 10
  • (3, 5): 3 + 5 + 1 - 2 = 7

然后发现它用两个循环来检查所有可能的数字组合:

  • 外循环:  从第一个数字开始,依次检查到倒数第二个数字。
  • 内循环:  对于外循环选中的每个数字,内循环从它后面的数字开始,检查到最后一个数字。

这样就能保证每对数字都只被检查一次,不会重复计算。

每次检查一对数字,程序就按照上面的规则计算分数,然后看看这个分数是不是比之前找到的最高分数还高。如果是,就更新最高分数。

最后,程序返回找到的最高分数。

最终在不断修改之后的情况下,终于得到了此题的最终解题答案:def solution(values: list) -> int: max_score = 0 n = len(values) for i in range(n - 1): for j in range(i + 1, n): score = values[i] + values[j] + i - j max_score = max(max_score, score) return max_score

if name == 'main': print(solution(values=[8, 3, 5, 5, 6]) == 11) print(solution(values=[10, 4, 8, 7]) == 16) print(solution(values=[1, 2, 3, 4, 5]) == 8)