O(n) Math solution.
/**
* F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]
* = 0 * Bk-1[n-1] + 1 * Bk-1[0] + ... + (n-1) * Bk-1[n-2]
* F(k-1) = 0 * Bk-1[0] + 1 * Bk-1[1] + ... + (n-1) * Bk-1[n-1]
*
* F(k) - F(k-1) = 1*Bk-1([0]-[1]) + 2*Bk-1([1]-[2]) + (n-1)*Bk-1([n-2]-[n-1]) = sum_of_array - nBk-1[n-1] = sum_of_array - nBk[0]
*
* B1[0] = A[len-1]
* B2[0] = A[len-2]
* ...
* Blen-1[0] = A[1]
*/
public class Solution {
public int maxRotateFunction(int[] A) {
int len = A.length;
// Calculate the sum of the array and F(0)
int sum = 0;
int f = 0;
for (int i=0; i<len; i++) {
sum += A[i];
f += (i * A[i]);
}
// From length-1 to 1 calculate Fk, save the max value
int max = f;
for (int j=len-1; j>=1; j--) {
f = f + sum - len * A[j];
max = Math.max(f, max);
}
return max;
}
}
Straightforward O(n^2) solution.
public class Solution {
public int maxRotateFunction(int[] A) {
if (A == null || A.length == 0) {
return 0;
}
int n = A.length;
int max = Integer.MIN_VALUE;
for (int k=0; k<n; k++) {
// Rotate the array
int[] temp = rotate(A, k);
// Calculate the F(k)
int curr = calculateF(temp);
// Compare and set max value
max = Math.max(curr, max);
}
return max;
}
// Rotate the given by k clockwise
public int[] rotate(int[] A, int k) {
int len = A.length;
int[] rotated = new int[len];
// Move last k elements in A to the head of the new created array
for (int i=0; i<k; i++) {
rotated[i] = A[len-k+i];
}
// Move first len - k elements to the tail of the rotated array
for (int i=0; i<len-k; i++) {
rotated[k+i] = A[i];
}
return rotated;
}
// Calculate the F value for rotated array
public int calculateF(int[] rotated) {
int sum = 0;
for (int i=0; i<rotated.length; i++) {
sum += (i * rotated[i]);
}
return sum;
}
}