问题描述
小R正在研究一组观光景点,每个景点都有一个评分,保存在数组 values 中,其中 values[i] 表示第 i 个观光景点的评分。同时,景点之间的距离由它们的下标差 j - i 表示。
一对景点 (i < j) 的观光组合得分为 values[i] + values[j] + i - j,也就是两者评分之和减去它们之间的距离。
小R想知道,在哪种情况下能够获得观光景点组合的最高得分。
约束条件:
- 2 <=
values.length - 1 <=
values[i]<= 1000
测试样例
样例1:
输入:
values = [8, 3, 5, 5, 6]
输出:11
样例2:
输入:
values = [10, 4, 8, 7]
输出:16
样例3:
输入:
values = [1, 2, 3, 4, 5]
输出:8
题解
function solution(values) {
let maxScore = 0;
let maxVal = values[0] + 0; // 初始化为第一个景点的 values[0] + 0
for (let j = 1; j < values.length; j++) {
// 计算当前景点 j 的得分
maxScore = Math.max(maxScore, maxVal + values[j] - j);
// 更新 maxVal 为当前最大值
maxVal = Math.max(maxVal, values[j] + j);
}
return maxScore;
}
function main() {
console.log(solution([8, 3, 5, 5, 6]) === 11 ? 1 : 0);
console.log(solution([10, 4, 8, 7]) === 16 ? 1 : 0);
console.log(solution([1, 2, 3, 4, 5]) === 8 ? 1 : 0);
}
main();
解题思路
题目要求我们找到一对景点 (i, j) 使得 values[i] + values[j] + i - j 最大,其中 i < j。我们可以将这个表达式拆分为两部分:values[i] + i 和 values[j] - j。通过遍历数组,我们可以动态地维护 values[i] + i 的最大值,并在每次遍历到 j 时计算 values[j] - j 与当前最大值的和,从而得到当前的最大得分。
-
初始化:初始化
maxScore为 0,表示当前的最大得分;初始化maxVal为values[0],表示当前values[i] + i的最大值。 -
遍历数组:从第二个元素开始遍历数组,对于每个
j:- 计算当前的得分
maxVal + values[j] - j,并更新maxScore为当前得分和maxScore中的较大值。 - 更新
maxVal为values[j] + j和maxVal中的较大值,以确保maxVal始终为values[i] + i的最大值。
- 计算当前的得分
-
返回结果:遍历结束后,
maxScore即为所求的最大得分。
复杂度分析
- 时间复杂度:O(n),其中 n 是数组
values的长度。我们只需要遍历数组一次。 - 空间复杂度:O(1),我们只使用了常数级别的额外空间。
知识点扩展
- 动态规划:本题通过动态地维护
values[i] + i的最大值,避免了重复计算,体现了动态规划的思想。 - 数组操作:通过遍历数组,我们能够高效地处理每个元素,并更新相关的状态。
- 优化问题:题目要求找到一对景点的最大得分,通过拆分表达式并动态维护最大值,我们能够高效地解决这类优化问题。