观光景点组合得分问题

76 阅读2分钟

问题描述

小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

代码展示 public class Main { public static int solution(int[] values) { if (values == null || values.length < 2) { return 0; }

    int n = values.length;
    int maxScore = Integer.MIN_VALUE;
    int maxValuesIPlusI = Integer.MIN_VALUE;

    for (int j = 0; j < n; j++) {
        // 更新最大得分
        if (j > 0) {
            maxScore = Math.max(maxScore, maxValuesIPlusI + values[j] - j);
        }
        // 更新 maxValuesIPlusI
        maxValuesIPlusI = Math.max(maxValuesIPlusI, values[j] + j);
    }

    return maxScore;
}

public static void main(String[] args) {
    System.out.println(solution(new int[]{8, 3, 5, 5, 6}) == 11 ? 1 : 0);
    System.out.println(solution(new int[]{10, 4, 8, 7}) == 16 ? 1 : 0);
    System.out.println(solution(new int[]{1, 2, 3, 4, 5}) == 8 ? 1 : 0);
}

}

问题描述

我们需要找到一对景点 (i, j) 使得它们的组合得分 values[i] + values[j] + i - j 最大。我们将这个公式重写为 (values[i] + i) + (values[j] - j),这样可以分别处理两个部分:

  1. values[i] + i
  2. values[j] - j

我们需要找到一个最大的 values[i] + i 和一个最大的 values[j] - j,并且确保 i < j

解决方案

  1. 初始化

    • maxScore 用于存储当前的最大得分。
    • maxValuesIPlusI 用于存储 values[i] + i 的最大值。
  2. 遍历数组

    • 对于每个 j,计算 values[j] - j
    • 更新 maxScore 为 maxValuesIPlusI + values[j] - j 的最大值。
    • 更新 maxValuesIPlusI 为 values[j] + j 的最大值。

详细解析

  1. 初始化

    java
    int maxScore = Integer.MIN_VALUE;
    int maxValuesIPlusI = Integer.MIN_VALUE;
    
    • maxScore 用于存储当前的最大得分。
    • maxValuesIPlusI 用于存储 values[i] + i 的最大值。
  2. 遍历数组

    java
    for (int j = 0; j < n; j++) {
        // 更新最大得分
        if (j > 0) {
            maxScore = Math.max(maxScore, maxValuesIPlusI + values[j] - j);
        }
        // 更新 maxValuesIPlusI
        maxValuesIPlusI = Math.max(maxValuesIPlusI, values[j] + j);
    }
    
    • 对于每个 j,我们计算 values[j] - j
    • 如果 j > 0,我们更新 maxScore 为 maxValuesIPlusI + values[j] - j 的最大值。
    • 更新 maxValuesIPlusI 为 values[j] + j 的最大值。
  3. 返回结果

    java
    return maxScore;
    

测试样例

  • 样例1values = [8, 3, 5, 5, 6]

    • 计算过程:

      • maxValuesIPlusI 依次为 8, 5, 8, 9, 11
      • maxScore 依次为 8, 8, 11, 11, 11
    • 最终结果:11

  • 样例2values = [10, 4, 8, 7]

    • 计算过程:

      • maxValuesIPlusI 依次为 10, 10, 10, 11
      • maxScore 依次为 10, 10, 16, 16
    • 最终结果:16

  • 样例3values = [1, 2, 3, 4, 5]

    • 计算过程:

      • maxValuesIPlusI 依次为 1, 3, 5, 7, 9
      • maxScore 依次为 1, 3, 5, 7, 8
    • 最终结果:8

通过这种方式,我们可以在一次遍历中找到最优解,时间复杂度为 O(n)。