leetcode_396

Rotate Function

题目戳这

题意

给定一个数组A,求所有它的旋转数组B的函数值中的 最大值,比如当A = [4,3,2,6]时,求解过程如下:

1
2
3
4
5
6
7
8
A = [4, 3, 2, 6]
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26.

解法

此题的n是<=10^5的,那么传统的暴力求解就不可行了。我们观察F[1]-F[0],F[2]-F[1]的差值可以发现是有规律的,假设A长度为5,那么

F[0] = A[1]+2*A[2]+3*A[3]+4*A[4]

F[1] = A[0]+2*A[1]+3*A[2]+4*A[3]

那么
F[1]-F[0]=A[0]+A[1]+A[2]+A[3]-4A[4]=A[0]+A[1]+A[2]+A[3]+A[4]-5*A[4]

同理可得
F[2]-F[1]=A[0]+A[1]+A[2]+A[3]+A[4]-5*A[3]

从上面的推导可以看出
F[n] = F[n-1]+sum(A)-len(A)*A[len(A)-n]
这样就可以根据这个公式进行递推了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution(object):
def maxRotateFunction(self, A):
"""
:type A: List[int]
:rtype: int
"""
alen = len(A)
if not A:
return 0
mmax = 0
pre = 0
ssum = 0
for i in range(alen):
mmax += i*A[i]
ssum += A[i]
pre = mmax
for i in range(1,alen):
after = pre + ssum - alen*A[alen-i]
mmax = max(mmax, after)
pre = after
return mmax