Given an array of integers A
and let n to be its length.
Assume Bk
to be an array obtained by rotating the array A
k positions clock-wise, we define a "rotation function" F
on A
as follow:
F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]
.
Calculate the maximum value of F(0), F(1), ..., F(n-1)
.
Note:
n is guaranteed to be less than 105.
Example:
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.
一开始采用了最简单的方法,每次求完一组和,将数组的元素移动一次。
class Solution {
public:
int maxRotateFunction(vector<int>& A) {
int i, j;
int f = 0;
for (i = 0; i < A.size(); ++i) {
f += i * A[i];
}
for (i = 1; i < A.size(); ++i) {
Rotate(A);
int tmp = 0;
for (j = 0; j < A.size(); ++j) {
tmp += j * A[j];
}
if (tmp > f) {
f = tmp;
}
}
return f;
}
void Rotate(vector<int>& A) {
int i;
int tmp = A[A.size() - 1];
for (i = A.size() - 1; i > 0; --i) {
A[i] = A[i - 1];
}
A[i] = tmp;
}
};
每次交换的次数为A.size() ,并且交换完成之后还有在进行计算,时间复杂度为O(n2 + n2)。
由于交换对复杂度的影响很大,因此第二种方法,采用每次取余的方法,对下标进行计算。
class Solution {
public:
int maxRotateFunction(vector<int>& A) {
int i, j;
int f = 0;
for (i = 0; i < A.size(); ++i) {
f += i * A[i];
}
for (i = 1; i < A.size(); ++i) {
int tmp = 0;
int cnt = 0;
for (j = i; cnt < A.size();) {
tmp += cnt * A[j];
++cnt;
j = (j + 1) % A.size();
}
if (tmp > f) {
f = tmp;
}
}
return f;
}
};
这种方法虽然避免了每次元素的交换,但复杂度依然为O(n2)。
以上两种方法不能对A中元素个数非常大的情况下在要求的时间内计算出结果。
于是,对题目中计算F的方法进行下手。
F(0) = 0*A[0] + 1*A[1] + ...... + (n-1)*A[n-1]F(1) = 0 *A[n-1] + 1*A[0] + 2*A[1] + 3*A[2] + ...... + (n-1)*A[n-2]
F(2) = 0 *A[n-2] + 1*A[n-1] + 2*A[0] + 3*A[1] + ..... + (n-1)*A[n-3]
.
.
F(n-1) = 0*A[1] + 1*A[2] + 2*A[3] + ...... + (n-1)*A[0]
F(1) - F(0) = A[0] + A[1] + A[2] + ...... + A[n-2] - (n-1)*A[n-1]
= A[0] + A[1] + A[2] + ...... + A[n-2] + A[n-1] - n*A[n-1]
F(2) - F(1) = A[0] + A[1] + A[2] + ...... + A[n-3] - (n-1)*A[n-2] + A[n-1]
= A[0] + A[1] + A[2] + ...... + A[n-1] - (n-1)*A[n-2]
F(1) = A[0] + A[1] + A[2] + ...... + A[n-1] - n*A[n-1] + F(0)
F(2) = A[0] + A[1] + A[2] + ...... + A[n-1] - n*A[n-2] + F(1)
.
.
F(i) = A[0] + A[1] + A[2] + ...... + A[n-1] - n*A[n-i] + F(i-1)
根据最后得出的F(i),先求出A[0...n-1]的和也就是F(0),然后再求出F(i),与F(i-1)进行比较即可。
class Solution {
public:
int maxRotateFunction(vector<int>& A) {
int i, j;
int sum = 0;
int f = 0;
for (i = 0; i < A.size(); ++i) {
sum += A[i];
f += i * A[i];
}
int ret = f;
for (i = 1; i < A.size(); ++i) {
f = sum + f - A.size() * A[A.size() - i];
if (f > ret) {
ret = f;
}
}
return ret;
}
};
利用这种方法计算出结果的时间复杂度为O(n)。