题目解析:观光景点得分
这道题的目标是计算一对观光景点组合的得分,并找出能获得最高得分的景点组合。每个景点的得分由两个部分构成:景点的评分和它们之间的距离。给定一个数组 values,其中 values[i] 表示第 i 个景点的评分,景点之间的距离由下标差 j - i 表示。景点组合的得分公式为:
values[i] + values[j] + i - j
其中,i < j,即我们必须选择两个不同的景点,i 为较小的下标,j 为较大的下标。
问题分析
我们需要通过遍历数组,计算所有可能的景点组合的得分,并找出最大得分。为了避免直接遍历所有组合,这道题可以通过一些优化来减少计算量。
优化思路
观察公式:
values[i] + values[j] + i - j
我们可以将公式拆分为两个部分:
values[i] + ivalues[j] - j
注意到,对于固定的 j,我们可以选择之前的 i 来计算得分。在遍历过程中,记录 values[i] + i 的最大值,我们就能通过下面的方式快速计算得分:
score = (values[i] + i) + (values[j] - j)
为了更高效地计算,我们可以维护一个变量 max_i_value 来记录当前 i 的最大得分 values[i] + i,每次计算得分时,直接使用这个最大值。
解题步骤
-
初始化
max_score为 0,表示目前的最大得分。 -
初始化
max_i_value为values[0] + 0,记录初始时的最大得分。 -
遍历数组,从
j = 1开始:- 对于每个
j,计算max_score = max(max_score, max_i_value + values[j] - j)。 - 更新
max_i_value为max(max_i_value, values[j] + j)。
- 对于每个
-
最终返回
max_score,即为最大得分。
代码实现
def solution(values: list) -> int:
max_score = 0 # 最大得分初始化
max_i_value = values[0] # 记录 values[i] + i 的最大值
# 遍历每个景点作为 j,i < j
for j in range(1, len(values)):
# 计算当前组合的得分 values[i] + values[j] + i - j
max_score = max(max_score, max_i_value + values[j] - j)
# 更新 max_i_value,使其总是保持最大值
max_i_value = max(max_i_value, values[j] + j)
return max_score
# 测试用例
if __name__ == '__main__':
print(solution([8, 3, 5, 5, 6]) == 11) # True
print(solution([10, 4, 8, 7]) == 16) # True
print(solution([1, 2, 3, 4, 5]) == 8) # True
代码解析
-
初始化
max_score和max_i_value:max_score用来记录目前为止的最大得分,初始为 0。max_i_value用来记录当前i位置的values[i] + i的最大值,初始为values[0]。
-
遍历数组:
- 从
j = 1开始遍历数组,对于每一个j,计算与之前的最大i组合的得分,并更新max_score。 - 同时更新
max_i_value,确保它始终存储values[i] + i的最大值。
- 从
-
返回结果:
- 最终,
max_score存储的是能得到的最大得分。
- 最终,
时间复杂度
- 时间复杂度是 O(n),其中 n 是
values数组的长度。我们只需要遍历数组一次,每次操作都是常数时间,因此时间复杂度为 O(n)。
测试用例分析
-
测试用例 1:
values = [8, 3, 5, 5, 6]- 最佳组合是选择景点 0 和景点 4,得分为
8 + 6 + (0 - 4) = 11。 - 返回值为
11。
- 最佳组合是选择景点 0 和景点 4,得分为
-
测试用例 2:
values = [10, 4, 8, 7]- 最佳组合是选择景点 0 和景点 2,得分为
10 + 8 + (0 - 2) = 16。 - 返回值为
16。
- 最佳组合是选择景点 0 和景点 2,得分为
-
测试用例 3:
values = [1, 2, 3, 4, 5]- 最佳组合是选择景点 0 和景点 4,得分为
1 + 5 + (0 - 4) = 8。 - 返回值为
8。
- 最佳组合是选择景点 0 和景点 4,得分为
总结
本题通过优化组合得分的计算方式,利用 max_i_value 来避免暴力计算所有 i 和 j 的组合,从而减少了计算量。该方法的时间复杂度为 O(n),能够在较大的输入规模下高效运行。