问题描述
小R正在研究一组观光景点,每个景点都有一个评分,保存在数组 values 中,其中 values[i] 表示第 i 个观光景点的评分。同时,景点之间的距离由它们的下标差 j - i 表示。
一对景点 (i < j) 的观光组合得分为 values[i] + values[j] + i - j,也就是两者评分之和减去它们之间的距离。
小R想知道,在哪种情况下能够获得观光景点组合的最高得分。
测试样例
样例1:
输入:
values = [8, 3, 5, 5, 6]
输出:11
样例2:
输入:
values = [10, 4, 8, 7]
输出:16
样例3:
输入:
values = [1, 2, 3, 4, 5]
输出:8
问题分析
题目要求我们找到一对景点 (i, j) 使得 values[i] + values[j] + i - j 的值最大,其中 i < j。如果我们直接暴力求解,即对每一个 i 和 j 进行两层循环计算得分,那么时间复杂度将是 O(n^2),这对于较大的数组来说效率较低。
优化思路
我们可以利用一个变量 max_i_plus_value 来存储 values[i] + i 的最大值。这样在遍历到 j 时,可以直接用这个最大值来计算得分,而不需要每次都从头开始找最大的 values[i] + i。
具体步骤如下:
-
初始化:
- 设定
max_i_plus_value为第一个景点的values[0] + 0。 - 设定
max_score为负无穷大,用于记录当前的最大得分。
max_i_plus_value = values[0] + 0 max_score = float('-inf')这里我们将
max_i_plus_value初始化为第一个景点的values[0] + 0,并将max_score初始化为负无穷大,表示还没有计算过任何得分。 - 设定
-
遍历景点:
- 从第二个景点开始遍历(因为
j > i)。 - 对于每个景点 j,计算当前的最大得分
current_score = max_i_plus_value + values[j] - j。 - 更新
max_score,使其保持为所有计算过的得分中的最大值。 - 更新
max_i_plus_value,确保其始终为values[i] + i的最大值,以便在后续计算中使用。
- 从第二个景点开始遍历(因为
for j in range(1, n):
current_score = max_i_plus_value + values[j] - j
max_score = max(max_score, current_score)
max_i_plus_value = max(max_i_plus_value, values[j] + j)
在每次迭代中,我们计算当前景点 j 的得分,并更新 max_score。同时,我们也更新 max_i_plus_value,以确保它始终是 values[i] + i 的最大值。
-
返回结果:
- 最终返回
max_score,这就是所有可能的观光组合中的最高得分。
- 最终返回
通过这种方法,我们只需要一次遍历即可找到观光景点组合的最高得分,时间复杂度降到了 O(n),大大提高了效率。
以下是具体的Python代码实现:
def maxScoreSightseeingPair(values):
n = len(values)
if n < 2:
return 0
# 初始化第一个景点的 values[i] + i
max_i_plus_value = values[0] + 0
max_score = float('-inf')
for j in range(1, n):
# 计算当前的最大得分
current_score = max_i_plus_value + values[j] - j
max_score = max(max_score, current_score)
# 更新 max_i_plus_value
max_i_plus_value = max(max_i_plus_value, values[j] + j)
return max_score
# 测试样例
print(maxScoreSightseeingPair([8, 3, 5, 5, 6])) # 输出:11
print(maxScoreSightseeingPair([10, 4, 8, 7])) # 输出:16
print(maxScoreSightseeingPair([1, 2, 3, 4, 5])) # 输出:8