LeetCode Rotate Function

来源:互联网 发布:经合组织数据库 编辑:程序博客网 时间:2024/04/27 15:06

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 = 25F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26So 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)。

0 0
原创粉丝点击