LT396. 旋转函数]
396. 旋转函数
问题描述
给定一个长度为 n
的整数数组 nums
。
假设 arrk
是数组 nums
顺时针旋转 k
个位置后的数组,我们定义 nums
的 旋转函数 F
为:
F(k) = 0 * arrk[0] + 1 * arrk[1] + ... + (n - 1) * arrk[n - 1]
返回 F(0), F(1), ..., F(n-1)
中的最大值 。
生成的测试用例让答案符合 32 位 整数。
示例 1:
输入: nums = [4,3,2,6]
输出: 26
解释:
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
所以 F(0), F(1), F(2), F(3) 中的最大值是 F(3) = 26 。
示例 2:
输入: nums = [100]
输出: 0
提示:
n == nums.length
1 <= n <= 105
-100 <= nums[i] <= 100
解题思路与代码实现
class Solution {
/**
* 解题思路:
* 暴力破解失败
* 找规律,发现F(i+1)和F(i)的关系:F(i+1)=F(i)+数组和-数组长度n*nums[n-1](旋转i个位置的nums数组)
* 可以先计算F(0)和数组和,nums[n-1]则从初始nums数组的最后一个元素开始向左移动,一共移动n-1次
* 然后根据关系依次计算比较得到最大值
*/
public int maxRotateFunction(int[] nums) {
int initVal = 0; // 计算F(0)
int sum = 0; // 记录数组和
for (int i = 0; i < nums.length; i++) {
initVal += i * nums[i];
sum += nums[i];
}
int res = initVal; // 记录最终结果
int nextVal = initVal; // 记录F(i+1)
int index = nums.length - 1;
while (index > 0) {
// F(i+1)
nextVal = nextVal + sum - nums.length * nums[index];
index--;
// 比较取较大值
res = Math.max(res, nextVal);
}
return res;
}
}
关键点
找规律,发现F(i+1)和F(i)的关系:F(i+1)=F(i)+数组和-数组长度n*numsn-1