📅  最后修改于: 2023-12-03 15:04:41.122000             🧑  作者: Mango
题目描述:给定一个数组,只能通过旋转数组(即将数组的某些元素移动到末尾)来寻找新的 nums[]。求数组 nums[] 的 Sum(i*arr[i]) 的最大值。其中,i表示数组下标。
比如,对于数组nums=[1,2,3,4],共有4种旋转方式:
1 2 3 4 4 1 2 3 3 4 1 2 2 3 4 1
▲ ▲ ▲ ▲ ▲ ▲ ▲
对于每一个旋转后得到的数组,可以求得其 Sum(i*arr[i]) 的值:
i | 0 1 2 3
--------------------
原始 | 0 + 2 + 6 + 12 = 20
第一 | 0 + 2 + 6 + 12 = 20
第二 | 0 + 4 + 6 + 8 = 18
第三 | 0 + 6 + 4 + 2 = 12
第四 | 0 + 8 + 2 + 6 = 16
因此,最大的 Sum(i*arr[i]) 值为20。
对于 Sum(i*arr[i]),如果我们把 i 固定在某一个位置上,那么对于其他位置 j,它们的贡献就分别是 arr[j] 和 j。所以先求出所有的 arr[j] 的和,设为 sum。然后,从数组的第二位开始,依次把 arr[j] - arr[0] 赋值给 i。此时,i 为固定值,整个数组的贡献也就可以求出来了。
对于如何旋转数组,则可以采用三次翻转,具体步骤如下:
其中 k 为旋转的位置。
def find_max_sum(arr: List[int]) -> int:
sum_arr = sum(arr)
n = len(arr)
max_sum = float('-inf')
cur_sum = 0
for i in range(1, n):
cur_sum += (i * arr[i]) - sum_arr + arr[0]
max_sum = max(max_sum, cur_sum)
return max_sum
def rotate_array(arr: List[int], k: int) -> None:
n = len(arr)
k = k % n
arr.reverse()
reverse_array(arr, 0, k-1)
reverse_array(arr, k, n-1)
def reverse_array(arr: List[int], begin: int, end: int) -> None:
while begin < end:
arr[begin], arr[end] = arr[end], arr[begin]
begin += 1
end -= 1
nums = [1,2,3,4]
k = 1
rotate_array(nums, k)
print(find_max_sum(nums)) # 输出20