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

94 阅读3分钟

问题描述

小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 最大。这个得分可以分解为两部分:

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

数据结构选择

我们可以使用一个变量来记录当前遍历到的最大 values[i] + i,然后在遍历 j 时,计算 values[j] - j 并加上这个最大值,来更新最大得分。

算法步骤

  1. 初始化变量

    • max_score:用于记录最大得分,初始值为负无穷大。
    • max_i_plus_value:用于记录当前遍历到的最大 values[i] + i,初始值为 values[0] + 0
  2. 遍历数组

    • 从 j = 1 开始遍历数组 values
    • 对于每个 j,计算当前组合的得分 max_i_plus_value + values[j] - j
    • 更新 max_score 如果当前得分更大。
    • 更新 max_i_plus_value 如果 values[j] + j 更大。
  3. 返回结果

    • 遍历结束后,max_score 即为所求的最大得分。

时间复杂度

这个算法的时间复杂度是 O(n),因为我们只需要遍历数组一次。

空间复杂度

空间复杂度是 O(1),因为我们只使用了常数个额外的变量。

详细步骤

  1. 初始化

    • max_score = float('-inf')
    • max_i_plus_value = values[0] + 0
  2. 遍历数组

    • 从 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
  3. 返回结果

    • 遍历结束后,返回 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)

总结

其实就是一道普通的贪心的题目,遍历一遍找到最大值即可。