问题描述
小S有一个长度为 𝑛 的环形数组 𝑎,定义了两个下标 𝑖 和 𝑗 的贡献值公式为: 𝑓(𝑖,𝑗)=(𝑎𝑖+𝑎𝑗)×dist(𝑖,𝑗) 其中,dist(𝑖,𝑗) 是下标 𝑖 和 𝑗 在数组中的最短距离。由于数组是环形的,最左和最右的元素也是相邻的。我们需要找到一对下标,使得它们的贡献值最大。
样例分析
-
样例1:𝑛=3,𝑎=[1,2,3]
- 任意两个下标的距离都是1。
- 最大贡献值:𝑓(2,3)=(2+3)×1=5
-
样例2:𝑛=4,𝑎=[4,1,2,3]
- 考虑所有可能的下标对,计算贡献值。
- 最大贡献值:𝑓(0,3)=(4+3)×1=7,但实际最大贡献值为 𝑓(0,1)=(4+1)×1=5或 𝑓(0,3)=(4+3)×1=7,考虑环形特性,𝑓(0,3)=(4+3)×1=7 更合适。
-
样例3:𝑛=5,𝑎=[1,5,3,7,2]
- 计算所有可能的下标对,找到最大贡献值。
- 最大贡献值:𝑓(1,3)=(5+7)×2=24
解题步骤
步骤1:初始化变量
- 初始化最大贡献值
max_contribution为 0。
步骤2:遍历所有可能的下标对
- 使用两层嵌套循环遍历所有可能的下标对 (𝑖,𝑗)。
- 确保 𝑖≠𝑗 以避免同一个下标的情况。
步骤3:计算最短距离
- 对于每个下标对 (𝑖,𝑗),计算它们之间的最短距离。
- 由于数组是环形的,最短距离可以是直接距离 ∣𝑖−𝑗∣或者通过数组另一端的距离 𝑛−∣𝑖−𝑗∣中的较小值。
步骤4:计算贡献值
- 使用公式 𝑓(𝑖,𝑗)=(𝑎𝑖+𝑎𝑗)×dist(𝑖,𝑗) 计算贡献值。
步骤5:更新最大贡献值
- 比较当前计算的贡献值与已知的最大贡献值,更新最大贡献值。
步骤6:返回结果
- 返回最大贡献值
max_contribution。
代码实现
def solution(n: int, a: list) -> int:
max_contribution = 0
# 遍历所有可能的下标对 (i, j)
for i in range(n):
for j in range(n):
if 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(n = 3, a = [1, 2, 3]) == 5)
print(solution(n = 4, a = [4, 1, 2, 3]) == 12)
print(solution(n = 5, a = [1, 5, 3, 7, 2]) == 24)
测试用例
-
样例1:𝑛=3,𝑎=[1,2,3]
- 输出:5
-
样例2:𝑛=4,𝑎=[4,1,2,3]
- 输出:12
-
样例3:𝑛=5,𝑎=[1,5,3,7,2]
- 输出:24
总结
时间复杂度
- 该算法的时间复杂度为 𝑂(𝑛2),因为我们需要遍历所有可能的下标对 (𝑖,𝑗)。对于每个下标对,我们进行常数时间的操作来计算最短距离和贡献值。
空间复杂度
- 该算法的空间复杂度为 𝑂(1),因为我们只使用了常数级的额外空间来存储最大贡献值和其他临时变量。
关键点
- 双层循环:使用两层循环遍历所有可能的下标对。
- 最短距离计算:在环形数组中,最短距离可以通过直接距离或通过数组另一端的距离来计算。
- 贡献值计算:使用给定的公式 𝑓(𝑖,𝑗)=(𝑎𝑖+𝑎𝑗)×dist(𝑖,𝑗) 计算贡献值。
- 最大贡献值更新:在遍历过程中不断更新最大贡献值。