环形数组中的最大贡献值 | 豆包Marscode AI 刷题

67 阅读3分钟

题解

问题描述

小S拿到了一个长度为 n 的环形数组,并定义了两个下标 ij 的贡献值公式为:

题目分析

为了最大化贡献值 f(i, j) = (a_i + a_j) × dist(i, j),我们需要同时优化 (a_i + a_j)dist(i, j)。由于 dist(i, j) 的最大值取决于数组的长度 n,通常情况下,高值的 a_ia_j 配合适当的距离可以获得更大的贡献值。

一种直接的方法是遍历所有可能的下标对,计算它们的贡献值,并记录最大的值。这种方法的时间复杂度为 O(n²),适用于数组规模较小的情况。

解题思路

我们需要在环形数组中找到两个下标 ij,使得贡献值 f(i, j) = (a_i + a_j) × dist(i, j) 最大。由于数组是环形的,dist(i, j)ij 在数组中的最短距离,可以通过 min(j - i, n - (j - i)) 计算得到。

一种直接的方法是遍历所有可能的下标对,计算其贡献值,并记录最大的值。这种方法的时间复杂度为 O(n²),适用于数组规模较小的情况。

优化方法

目前的解法采用双重循环,时间复杂度为 O(n²)。对于较大的数组,可以考虑以下优化策略:

  1. 双指针法:由于数组是环形的,可以将其展开为两倍长度的线性数组,然后使用滑动窗口来寻找最大贡献值。然而,由于贡献值不仅依赖于元素和,还依赖于距离,这种方法的效果有限。

  2. 预处理最大值:预先找到数组中的最大两个元素,并计算它们之间的最短距离。这种方法在某些情况下可以快速找到较大的贡献值,但无法保证找到全局最大值。

  3. 分治法:将数组分成较小的部分,分别计算每部分的最大贡献值,然后合并结果。这种方法复杂度较高,且实现难度较大。

综上,目前双重循环仍然是最直接且有效的方法,尤其在数组规模不大的情况下。

复杂度分析

  • 时间复杂度:O(n²),其中 n 是数组的长度。需要遍历所有可能的下标对。

  • 空间复杂度:O(1),只使用了常数级别的额外空间。

代码实现


理解环形数组的距离计算:

对于环形数组,任意两个下标 i 和 j 的距离 dist(i, j) 可以通过以下公式计算:
dist(i, j) = min((i - j) % n, (j - i) % n)
这里 % 是取模运算符,n 是数组的长度。
遍历所有可能的 (i, j) 对:

你需要遍历所有可能的 (i, j) 对,计算它们的贡献值 f(i, j),并找到最大值。
注意 i 和 j 不能相同,因为 dist(i, i) 为 0,贡献值也为 0。
计算贡献值:

对于每一对 (i, j),计算 f(i, j) = (a[i] + a[j]) * dist(i, j)。
更新最大贡献值:

在遍历过程中,记录并更新最大贡献值。

你可以根据这个框架继续完善代码,确保所有细节都正确实现。



这对我们完成题目有很大的帮助