问题描述
小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),其中 i < j,使得观光组合得分 values[i] + values[j] + i - j 最大。这个得分可以分解为两部分:
values[i] + ivalues[j] - j
数据结构选择
我们可以使用一个变量来记录当前遍历到的最大 values[i] + i,然后在遍历 j 时,计算 values[j] - j 并加上这个最大值,来更新最大得分。
算法步骤
-
初始化变量:
max_score:用于记录最大得分,初始值为负无穷大。max_i_plus_value:用于记录当前遍历到的最大values[i] + i,初始值为values[0] + 0。
-
遍历数组:
- 从
j = 1开始遍历数组values。 - 对于每个
j,计算当前组合的得分max_i_plus_value + values[j] - j。 - 更新
max_score如果当前得分更大。 - 更新
max_i_plus_value如果values[j] + j更大。
- 从
-
返回结果:
- 遍历结束后,
max_score即为所求的最大得分。
- 遍历结束后,
时间复杂度
这个算法的时间复杂度是 O(n),因为我们只需要遍历数组一次。
空间复杂度
空间复杂度是 O(1),因为我们只使用了常数个额外的变量。
详细步骤
-
初始化:
max_score = float('-inf')max_i_plus_value = values[0] + 0
-
遍历数组:
-
从
j = 1开始遍历数组values。 -
对于每个
j:- 计算当前组合的得分
current_score = max_i_plus_value + values[j] - j。 - 如果
current_score > max_score,则更新max_score。 - 如果
values[j] + j > max_i_plus_value,则更新max_i_plus_value。
- 计算当前组合的得分
-
-
返回结果:
- 遍历结束后,返回
max_score。
- 遍历结束后,返回
题解
以下为golang版本代码,尚未评测(未上线)
package main
import "fmt"
func solution(values []int) int {
// write code here
n := len(values)
if n == 1{
return 0
}
maxResult := values[0] + values[1] + 0 - 1
for i := 1; i < n; i++{
for left, right := 0, i; right < n; left, right = left + 1, right + 1{
val := values[left] + values[right] + left - right
if val > maxResult {
maxResult = val
}
}
}
fmt.Println(maxResult)
return maxResult
}
func main() {
fmt.Println(solution([]int{8, 3, 5, 5, 6}) == 11)
fmt.Println(solution([]int{10, 4, 8, 7}) == 16)
fmt.Println(solution([]int{1, 2, 3, 4, 5}) == 8)
}
以下为python版本代码,由marscode转化而来
def solution(values: list) -> int:
n = len(values)
if n == 1:
return 0
# 初始化最大得分和当前最大 values[i] + i
max_score = float('-inf')
max_i_plus_value = values[0] + 0
# 遍历数组
for j in range(1, n):
# 计算当前组合的得分
current_score = max_i_plus_value + values[j] - j
# 更新最大得分
if current_score > max_score:
max_score = current_score
# 更新当前最大 values[i] + i
if values[j] + j > max_i_plus_value:
max_i_plus_value = 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)
总结
其实就是一道普通的贪心的题目,遍历一遍找到最大值即可。