寻找观光景点组合的最高得分| 豆包MarsCode AI 刷题

问题描述

假设我们有一组观光景点,每个景点都有一个评分,保存在数组 values 中。其中 values[i] 表示第 i 个景点的评分。景点之间的距离则通过下标差值 ∣j−i| 来衡量。

景点组合的得分由以下公式计算:

values[i] + values[j] + i − j

其中,i 和 j 满足 i < j。显然,这里的组合得分受到评分和距离的共同影响。目标是找到一种组合,使得得分最大化。


解题思路

公式重构

通过观察公式 values[i] + values[j] + i − j,我们可以将其分解为:

(values[i] + i ) + (values[j] − j)

这个形式揭示了一个关键点:最高得分的计算可以看作是两部分的加和:

  1. 左侧的最大值 (values[i] + i ) ,只与第 i 个景点有关。
  2. 当前景点的值减去其下标 (values[j] − j)

在整个数组遍历过程中,左侧的最大值 (values[i] + i ) 是动态变化的。因此,我们只需在遍历数组时动态维护左侧的最大值 (values[i] + i ) ,同时计算每个位置的得分。这样,问题的求解可以优化为 O(n) 时间复杂度。


算法步骤

通过上述分析,我们可以设计一个高效算法:

  1. 初始化变量 maxScore 为 0,用于记录当前的最高得分。

  2. 初始化变量 maxLeftvalues[0] + 0,表示初始的左侧最大值。

  3. 遍历数组的每一个位置 j(从 1 开始):

    • 计算当前组合的得分:maxLeft + values[j] - j
    • 如果得分更高,更新 maxScore
    • 更新左侧最大值 maxLeftmax(maxScore, maxLeft + values[j] - j) ,为后续计算提供支持。
  4. 遍历完成后,返回 maxScore


代码实现(Java)

以下是基于上述思路的 Java 实现代码:

ini 复制代码
public class SightseeingPair {
    public int maxScoreSightseeingPair(int[] values) {
        int maxScore = 0; // 初始化最高得分
        int maxLeft = values[0]; // 初始的左侧最大值
        
        for (int j = 1; j < values.length; j++) {
            // 计算当前组合得分
            maxScore = Math.max(maxScore, maxLeft + values[j] - j);
            // 更新左侧最大值
            maxLeft = Math.max(maxLeft, values[j] + j);
        }
        
        return maxScore;
    }
}

示例分析

输入:

ini 复制代码
int[] values = {8, 1, 5, 2, 6};
SightseeingPair sp = new SightseeingPair();
System.out.println(sp.maxScoreSightseeingPair(values)); // 输出: 11

算法复杂度分析

  • 时间复杂度: O(n)。数组仅遍历一次,每次操作均为常数时间。
  • 空间复杂度: O(1)。只使用了少量变量,未使用额外的存储空间。

相比于暴力解法 O(n^2) 的复杂度,这种优化算法显著提升了效率,尤其是在数组较大的情况下。


思考与总结

这个问题其实暴力法很简单就能做出,写文章的目的是为了记录、引导编程思想,用更有效率的算法解决问题。这也是动态规划、回溯等等算法的优势所在,学习常见的算法也是很有必要的。

相关推荐
Find24 天前
MaxKB 集成langchain + Vue + PostgreSQL 的 本地大模型+本地知识库 构建私有大模型 | MarsCode AI刷题
青训营笔记
理tan王子24 天前
伴学笔记 AI刷题 14.数组元素之和最小化 | 豆包MarsCode AI刷题
青训营笔记
理tan王子24 天前
伴学笔记 AI刷题 25.DNA序列编辑距离 | 豆包MarsCode AI刷题
青训营笔记
理tan王子24 天前
伴学笔记 AI刷题 9.超市里的货物架调整 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵1 个月前
分而治之,主题分片Partition | 豆包MarsCode AI刷题
青训营笔记
三六1 个月前
刷题漫漫路(二)| 豆包MarsCode AI刷题
青训营笔记
tabzzz1 个月前
突破Zustand的局限性:与React ContentAPI搭配使用
前端·青训营笔记
Serendipity5651 个月前
Go 语言入门指南——单元测试 | 豆包MarsCode AI刷题;
青训营笔记
wml1 个月前
前端实践-使用React实现简单代办事项列表 | 豆包MarsCode AI刷题
青训营笔记
用户44710308932421 个月前
详解前端框架中的设计模式 | 豆包MarsCode AI刷题
青训营笔记