使用 Python 解题 - 观光景点组合得分问题

一,题目详情

1,问题描述

小R正在研究一组观光景点,每个景点都有一个评分,保存在数组 values 中,其中 values[i] 表示第 i 个观光景点的评分。同时,景点之间的距离由它们的下标差 j - i 表示。

一对景点 (i < j) 的观光组合得分为 values[i] + values[j] + i - j,也就是两者评分之和减去它们之间的距离。

小R想知道,在哪种情况下能够获得观光景点组合的最高得分。

2,测试样例

样例1:

输入: values = [8, 3, 5, 5, 6]

输出: 11

解释:最高得分的组合是 (0, 4),得分为 8 + 6 + 0 - 4 = 11。

样例2:

输入: values = [10, 4, 8, 7]

输出: 16

解释:最高得分的组合是 (0, 2),得分为 10 + 8 + 0 - 2 = 16。

样例3:

输入: values = [1, 2, 3, 4, 5]

输出: 8

解释:最高得分的组合是 (3, 4),得分为 4 + 5 + 3 - 4 = 8。

3,约束条件

  • 2 ≤ values.length ≤ 1000
  • 1 ≤ values[i] ≤ 1000

二,解题思路

1,问题分析

我们需要找到一对景点 (i < j),使得 values[i] + values[j] + i - j 最大。这个表达式可以重新排列为 (values[i] + i) + (values[j] - j)。因此,对于每个 j,我们需要找到前面所有 i 中 values[i] + i 的最大值,然后与 values[j] - j 相加,得到当前 j 的最大得分。

2,算法策略

我们可以使用动态规划的思想来解决这个问题:

  1. 初始化一个变量 max_so_far 来记录 values[i] + i 的最大值。
  2. 遍历数组,对于每个 j,计算当前 j 的 values[j] - j,并与 max_so_far 相加得到当前得分。
  3. 更新 max_so_far 为当前 j 的 values[j] + j 和 max_so_far 中的较大值。
  4. 在遍历过程中,记录所有得分中的最大值。

3,逐步推演(以样例1为例)

输入 values = [8, 3, 5, 5, 6],推演过程如下:

步骤 j values[j] values[j] - j max_so_far current_score max_score
初始 - - - 8 + 0 = 8 - -∞
1 1 3 3 - 1 = 2 8 8 + 2 = 10 10
2 2 5 5 - 2 = 3 8 8 + 3 = 11 11
3 3 5 5 - 3 = 2 8 8 + 2 = 10 11
4 4 6 6 - 4 = 2 8 8 + 2 = 10 11

最终结果 max_score = 11,与预期一致。

三,代码实现

Python复制

ini 复制代码
def solution(values: list) -> int:
    if len(values) < 2:
        return 0  # 根据约束条件,这行可能不会执行
    
    max_so_far = values[0] + 0
    max_score = float('-inf')
    
    for j in range(1, len(values)):
        current_score = max_so_far + (values[j] - j)
        if current_score > max_score:
            max_score = current_score
        # 更新max_so_far为当前j作为i时的最大值
        current_i_value = values[j] + j
        if current_i_value > max_so_far:
            max_so_far = current_i_value
    
    return max_score

1,复杂度分析

  • 时间复杂度:O(n)

    • 只需一次线性遍历(n为数组长度)
  • 空间复杂度:O(1)

    • 仅使用常数级额外空间

2,边界测试

Python复制

ini 复制代码
if __name__ == '__main__':
    # 常规测试
    print(solution([8, 3, 5, 5, 6]) == 11)
    print(solution([10, 4, 8, 7]) == 16)
    print(solution([1, 2, 3, 4, 5]) == 8)

    # 边界测试:数组长度为2
    print(solution([1, 2]) == 2)

    # 边界测试:所有元素相同
    print(solution([5, 5, 5, 5]) == 5 + 5 + 0 - 1 = 9)

四,总结

通过将问题转化为动态规划的形式,我们实现了:

  1. 线性时间复杂度:一次遍历解决问题
  2. 常数空间复杂度:无需额外存储空间
  3. 普适性:适用于所有整数数组

这种解法不仅高效,还展现了动态规划在算法中的巧妙应用。当遇到"需要在数组中找到最优组合"类问题时,动态规划往往是解决问题的关键钥匙。

相关推荐
景彡先生17 分钟前
Python requests详解:从入门到实战,HTTP请求的“瑞士军刀”
python
深度学习lover18 分钟前
<数据集>yolo螺丝螺母识别数据集<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·螺丝螺母识别
Geoking.19 分钟前
PyTorch 基础详解:tensor.item() 方法
人工智能·pytorch·python
ZIM学编程22 分钟前
「学长有话说」作为一个大三学长,我想对大一计算机专业学生说这些!
java·c语言·数据结构·c++·python·学习·php
没有钱的钱仔36 分钟前
conda 基础命令使用
python
程序员三藏42 分钟前
如何使用Selenium做自动化测试?
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
Python私教1 小时前
基于 Django 5 + DRF 构建博客系统后端接口(从建模到接口实现)
python·django·sqlite
南方的狮子先生1 小时前
【深度学习】60 分钟 PyTorch 极速入门:从 Tensor 到 CIFAR-10 分类
人工智能·pytorch·python·深度学习·算法·分类·1024程序员节
闲人编程2 小时前
Docker化你的Python应用:从开发到生产
python·docker·eureka·开发·生产·codecapsule
JJJJ_iii2 小时前
【机器学习10】项目生命周期、偏斜类别评估、决策树
人工智能·python·深度学习·算法·决策树·机器学习