环形数组中最大贡献值的计算问题
问题描述
给定一个长度为 n 的环形数组 a,我们的目标是找到一对下标 (i, j),使得它们的贡献值最大。贡献值的计算公式如下:
[ f(i, j) = (a[i] + a[j]) \times \text{dist}(i, j) ]
其中,dist(i, j) 表示数组中下标 i 和下标 j 之间的最短距离。由于数组是环形的,因此 dist(i, j) 的计算需要考虑顺时针和逆时针两种路径。
思路解析
在处理此问题时,我们需要考虑以下几点:
-
环形数组的特点: 由于数组是环形的,即数组的最后一个元素与第一个元素相邻,因此在计算两下标间的距离时,不仅要考虑线性距离,还要考虑绕过数组一圈的距离。
-
最短距离的计算: 对于任意两个下标
i和j,最短距离dist(i, j)可以通过两种方式计算:- 线性距离:
|i - j| - 环形距离:
n - |i - j|
因此,
dist(i, j)应该取上述两者的最小值: [ \text{dist}(i, j) = \min(|i - j|, n - |i - j|) ] - 线性距离:
-
贡献值的计算: 对于每一对下标
(i, j),贡献值f(i, j)的计算公式为: [ f(i, j) = (a[i] + a[j]) \times \text{dist}(i, j) ]我们需要找到所有可能的
(i, j)组合中最大的贡献值。
解决方案
为了求解这个问题,我们可以使用以下步骤:
-
遍历所有可能的
(i, j): 我们可以通过嵌套的循环,遍历所有可能的i和j,计算每一对下标的贡献值。 -
计算最短距离: 对于每对
(i, j),计算它们之间的最短距离dist(i, j)。 -
更新最大贡献值: 计算每对下标的贡献值后,更新当前的最大贡献值。
算法实现
def solution(n: int, a: list) -> int:
max_contribution = 0
# 遍历所有的 i 和 j
for i in range(n):
for j in range(i + 1, n): # 确保 i < j,避免重复计算
# 计算最短距离
dist = min(abs(i - j), n - abs(i - j))
# 计算贡献值
contribution = (a[i] + a[j]) * dist
# 更新最大贡献值
max_contribution = max(max_contribution, contribution)
return max_contribution
# 测试样例
if __name__ == '__main__':
print(solution(3, [1, 2, 3])) # 输出: 5
print(solution(4, [4, 1, 2, 3])) # 输出: 12
print(solution(5, [1, 5, 3, 7, 2])) # 输出: 24
代码解释
-
输入参数: 函数
solution(n, a)接收两个参数:n表示数组的长度,a是长度为n的环形数组。 -
遍历所有
(i, j): 使用两个嵌套的for循环遍历所有可能的下标对(i, j)。由于我们只需要计算一次每对(i, j),因此内层循环从i + 1开始。 -
计算最短距离: 对于每一对
(i, j),我们首先计算它们之间的线性距离|i - j|,然后通过n - |i - j|计算环形距离,最终取这两者的最小值作为dist(i, j)。 -
计算贡献值: 对于每一对
(i, j),我们计算它们的贡献值f(i, j) = (a[i] + a[j]) * dist(i, j)。 -
更新最大贡献值: 在计算每对下标的贡献值时,我们不断更新当前的最大贡献值
max_contribution。 -
返回最大贡献值: 最后,返回所有计算中得到的最大贡献值。
复杂度分析
-
时间复杂度:由于我们需要遍历所有可能的
(i, j)对,并且每次计算贡献值的时间复杂度为常数O(1),因此总的时间复杂度为O(n^2)。对于较小的n,这个复杂度是可以接受的。 -
空间复杂度:算法只使用了常数空间来存储变量,因此空间复杂度是
O(1)。
测试用例
-
输入:
n = 3, a = [1, 2, 3]dist(0, 1) = 1, 贡献值为(1 + 2) * 1 = 3dist(0, 2) = 2, 贡献值为(1 + 3) * 2 = 8dist(1, 2) = 1, 贡献值为(2 + 3) * 1 = 5- 最大贡献值为
8。
-
输入:
n = 4, a = [4, 1, 2, 3]dist(0, 1) = 1, 贡献值为(4 + 1) * 1 = 5dist(0, 2) = 2, 贡献值为(4 + 2) * 2 = 12dist(0, 3) = 3, 贡献值为(4 + 3) * 3 = 21dist(1, 2) = 1, 贡献值为(1 + 2) * 1 = 3dist(1, 3) = 2, 贡献值为(1 + 3) * 2 = 8dist(2, 3) = 1, 贡献值为(2 + 3) * 1 = 5- 最大贡献值为
21。
-
输入:
n = 5, a = [1, 5, 3, 7, 2]- 计算所有的贡献值后,最大贡献值为
24。
- 计算所有的贡献值后,最大贡献值为
总结
在环形数组中计算最大贡献值的问题可以通过暴力遍历所有可能的 (i, j) 对来解决。通过巧妙地计算最短距离并优化贡献值的计算,我们能够高效地找到最大贡献值。尽管这个方法的时间复杂度是 O(n^2),但对于小规模数据,算法仍然能够在合理的时间内给出正确答案。