题解
问题描述
小S拿到了一个长度为 n 的环形数组,并定义了两个下标 i 和 j 的贡献值公式为:
题目分析
为了最大化贡献值 f(i, j) = (a_i + a_j) × dist(i, j),我们需要同时优化 (a_i + a_j) 和 dist(i, j)。由于 dist(i, j) 的最大值取决于数组的长度 n,通常情况下,高值的 a_i 和 a_j 配合适当的距离可以获得更大的贡献值。
一种直接的方法是遍历所有可能的下标对,计算它们的贡献值,并记录最大的值。这种方法的时间复杂度为 O(n²),适用于数组规模较小的情况。
解题思路
我们需要在环形数组中找到两个下标 i 和 j,使得贡献值 f(i, j) = (a_i + a_j) × dist(i, j) 最大。由于数组是环形的,dist(i, j) 是 i 和 j 在数组中的最短距离,可以通过 min(j - i, n - (j - i)) 计算得到。
一种直接的方法是遍历所有可能的下标对,计算其贡献值,并记录最大的值。这种方法的时间复杂度为 O(n²),适用于数组规模较小的情况。
优化方法
目前的解法采用双重循环,时间复杂度为 O(n²)。对于较大的数组,可以考虑以下优化策略:
-
双指针法:由于数组是环形的,可以将其展开为两倍长度的线性数组,然后使用滑动窗口来寻找最大贡献值。然而,由于贡献值不仅依赖于元素和,还依赖于距离,这种方法的效果有限。
-
预处理最大值:预先找到数组中的最大两个元素,并计算它们之间的最短距离。这种方法在某些情况下可以快速找到较大的贡献值,但无法保证找到全局最大值。
-
分治法:将数组分成较小的部分,分别计算每部分的最大贡献值,然后合并结果。这种方法复杂度较高,且实现难度较大。
综上,目前双重循环仍然是最直接且有效的方法,尤其在数组规模不大的情况下。
复杂度分析
-
时间复杂度: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)。
更新最大贡献值:
在遍历过程中,记录并更新最大贡献值。
你可以根据这个框架继续完善代码,确保所有细节都正确实现。
这对我们完成题目有很大的帮助