LintCode 1260: Rotate Function (好题)

本文探讨了一种名为旋转函数的问题,给出了三种不同复杂度的解决方案。通过实例解析,详细介绍了如何利用数组旋转特性,实现从O(n^2)到O(n)的时间复杂度优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. Rotate Function
    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).

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.
Notice
n is guaranteed to be less than 10^5.

解法1:
用两个A连起来。时间复杂度O(n^2)。

class Solution {
public:
    /**
     * @param A: an array
     * @return: the maximum value of F(0), F(1), ..., F(n-1)
     */
    int maxRotateFunction(vector<int> &A) {
        
        int len = A.size();
        if (len <= 1) return 0;

        int maxSum = INT_MIN;
        
        vector<int> newA = A;
        newA.insert(newA.end(), A.begin(), A.end());

        for (int i = 0; i <= len; ++i) {
            
            int sum = 0;
            for (int j = 0; j < len; ++j) {
                sum += newA[i + j] * j;
            }
            maxSum = max(maxSum, sum);
        }
        
        return maxSum;
    }
};

解法2:
跟解法1差不多,只是不用一个新数组。时间复杂度O(n^2)。

class Solution {
public:
    /**
     * @param A: an array
     * @return: the maximum value of F(0), F(1), ..., F(n-1)
     */
    int maxRotateFunction(vector<int> &A) {
        
        int len = A.size();
        if (len <= 1) return 0;

        int maxSum = INT_MIN;
        
        for (int i = 0; i <= len; ++i) {
            
            int sum = 0;
            for (int j = 0; j < len; ++j) {
                int index = (i + j) >= len ? (i + j) % len : (i + j);
                sum += A[index] * j;
            }
            maxSum = max(maxSum, sum);
        }
        
        return maxSum;
    }
};

解法3:参考九章。这个解法好。时间复杂度O(n)。
思路:
4 3 2 6 4 3 2 6
0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3
从下往上看:
f[0] = 4 * 0 + 3 * 1 + 2 * 2 + 6 * 3
f[1] = 4 * 1 + 3 * 2 + 2 * 3 + 6 * 0 = f[0] + sum - 6 * 4
f[2] = 4 * 2 + 3 * 3 + 2 * 0 + 6 * 1 = f[1] + sum - 2 * 4

可得
f[i] = f[i - 1] + sum - len * A[len - i];

class Solution {
public:
    /**
     * @param A: an array
     * @return: the maximum value of F(0), F(1), ..., F(n-1)
     */
    int maxRotateFunction(vector<int> &A) {
        
        int len = A.size();
        if (len <= 1) return 0;

        int sum = 0;
        vector<int> f(len, 0);
        
        for (int i = 0; i < len; ++i) {
            sum += A[i];
            f[0] += i * A[i];
        }
        
        int maxResult = f[0];
        for (int i = 1; i < len; ++i) {
            f[i] = f[i - 1] + sum - len * A[len - i];
            maxResult = max(maxResult, f[i]);
        }
        return maxResult;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值