观光景点组合得分问题 | 豆包MarsCode AI 刷题

67 阅读2分钟

问题描述

给定一个数组 values,其中 values[i] 表示第 i 个观光景点的评分。我们需要找到一对景点 (i, j),其中 i < j,使得它们的观光组合得分最大化。观光组合得分的计算公式为:

score=values[i]+values[j]+ij\text{score} = values[i] + values[j] + i - j

关键点分析

  1. 表达式的拆分

    • 观光组合得分公式可以拆分成两部分: score=(values[i]+i)+(values[j]j)\text{score} = (values[i] + i) + (values[j] - j)
    • 这样拆分的好处是可以分别处理 values[i] + ivalues[j] - j,从而简化问题。
  2. 动态更新

    • 我们可以在遍历数组的过程中,动态地更新两个关键变量:
      • max_i:当前遇到的最大 values[i] + i
      • max_score:当前遇到的最大观光组合得分。

解题步骤

  1. 初始化

    • max_i 初始化为 values[0] + 0,即第一个景点的评分加上它的下标。
    • max_score 初始化为 0,表示当前找到的最大观光组合得分。
  2. 遍历数组

    • 从第二个元素开始遍历数组(即从 j = 1 开始)。
    • 对于每个 j
      • 计算当前的观光组合得分 current_score = max_i + values[j] - j
      • 更新 max_score 为当前的最大值 max(max_score, current_score)
      • 更新 max_i 为当前的最大值 max(max_i, values[j] + j)
  3. 返回结果

    • 遍历结束后,max_score 就是最高得分。

示例解析

让我们通过一个具体的例子来理解这个过程。

示例1:values = [8, 3, 5, 5, 6]

  1. 初始化

    • max_i = 8 + 0 = 8
    • max_score = 0
  2. 遍历数组

    • j = 1
      • current_score = 8 + 3 - 1 = 10
      • max_score = max(0, 10) = 10
      • max_i = max(8, 3 + 1) = 8
    • j = 2
      • current_score = 8 + 5 - 2 = 11
      • max_score = max(10, 11) = 11
      • max_i = max(8, 5 + 2) = 8
    • j = 3
      • current_score = 8 + 5 - 3 = 10
      • max_score = max(11, 10) = 11
      • max_i = max(8, 5 + 3) = 8
    • j = 4
      • current_score = 8 + 6 - 4 = 10
      • max_score = max(11, 10) = 11
      • max_i = max(8, 6 + 4) = 10
  3. 返回结果

    • max_score = 11

完整代码

def solution(values: list) -> int:
    # 初始化 max_i 和 max_score
    max_i = values[0] + 0
    max_score = 0
    
    # 遍历数组,从第二个元素开始
    for j in range(1, len(values)):
        # 计算当前的观光组合得分
        current_score = max_i + values[j] - j
        # 更新最大得分
        max_score = max(max_score, current_score)
        # 更新 max_i
        max_i = max(max_i, values[j] + j)
    
    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)

时间和空间复杂度

  • 时间复杂度:(O(n)),其中 (n) 是数组的长度,因为我们只需要一次遍历数组。
  • 空间复杂度:(O(1)),因为我们只使用了常数级的额外空间。