📅  最后修改于: 2023-12-03 14:49:32.519000             🧑  作者: Mango
给定一个整数数组,等式 arr[i] + arr[j] + i - j(i < j)的值可能会有很多,找出其中最大的值并返回。
最简单的方法是暴力枚举所有可能的数对 (i, j),然后计算它们的值,选出最大的值。
时间复杂度: $O(N^2)$。
def max_value(arr):
"""
暴力破解
"""
n = len(arr)
res = float('-inf')
for i in range(n):
for j in range(i+1, n):
temp = arr[i] + arr[j] + i - j
if temp > res:
res = temp
return res
我们将 arr[i] + i 和 arr[j] - j 分别提出来,等式变成了:
(arr[i] + i) + (arr[j] - j)
其中,(arr[i] + i) 和 (arr[j] - j) 都只与数组 arr 有关,我们可以提前计算它们的值,然后枚举所有的数对 (i, j),找出它们的和的最大值。
时间复杂度: $O(N)$。
def max_value(arr):
"""
优化计算公式
"""
n = len(arr)
# 预处理数组
temp1 = [arr[i] + i for i in range(n)]
temp2 = [arr[j] - j for j in range(n)]
# 计算最大值
res = max(temp1[i] + temp2[j] for i in range(n) for j in range(n))
return res
我们注意到等式中有两个变量 i 和 j,我们可以固定其中的一个变量,另一个变量从左往右枚举,然后利用单调性快速找到最大值。
具体地,我们从左往右依次枚举变量 i,同时维护变量 j 的最大值以及其对应的等式最大值 mx:
mx = arr[i] + i + maxj # maxj 表示 j < i 时 arr[j] - j 的最大值
res = max(res, mx - i - arr[i])
maxj = max(maxj, arr[j] - j)
时间复杂度: $O(N)$。
def max_value(arr):
"""
优化枚举范围
"""
n = len(arr)
maxj = float('-inf')
res = float('-inf')
for i in range(n):
mx = arr[i] + i + maxj
res = max(res, mx - i - arr[i])
maxj = max(maxj, arr[j] - j)
return res
我们使用以下测试代码进行效果测试:
import random
# 测试次数
test_times = 10000
for i in range(test_times):
# 生成测试数组
n = random.randint(1, 100)
arr = [random.randint(-100, 100) for _ in range(n)]
# 分别测试三种算法
r1 = max_value(arr)
r2 = max_value_2(arr)
r3 = max_value_3(arr)
# 检查结果是否一致
if r1 != r2 or r2 != r3:
print(arr)
print(r1, r2, r3)
测试结果显示,三种算法都能通过上面的测试,且方法一和方法二的效率差不多,而方法三要略微快一些。