Leetcode-396-旋转函数
|字数总计:1.1k|阅读时长:5分钟|阅读量:|
题目
给定一个长度为 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
题目分析
数学推导
从特殊情况开始
F(0)=0⋅nums[0]+1⋅nums[1]+...+(n−2)⋅nums[n−2]+(n−1)⋅nums[n−1]
F(1)=1⋅nums[0]+2⋅nums[1]+...+(n−1)⋅nums[n−2]+0⋅nums[n−1]
F(2)=2⋅nums[0]+3⋅nums[1]+...+(n−1)⋅nums[n−3]+0⋅nums[n−2]+1⋅nums[n−1]
F(1)−F(0)=nums[0]+nums[1]+...+nums[n−1]+0⋅nums[n−1]−(n−1)⋅nums[n−1]
F(2)−F(1)=nums[0]+nums[1]+...+nums[n−3]+0⋅nums[n−3]−(n−1)⋅nums[n−2]+nums[n−1]
设S=nums[0]+nums[1]+...+nums[n]
F(1)=F(0)+S−nums[n−1]−(n−1)⋅nums[n−1]=F(0)+S−n⋅nums[n−1]
F(2)=F(1)+S−n⋅nums[n−2]
归纳到一般情况
更一般地,当1≤k<n有如下关系成立
F(k)=F(k−1)+S−n⋅nums[n−k]
这就是我们的状态转移方程。
特别地,当k=0
时,需要单独计算
F(0)=0⋅nums[0]+1⋅nums[1]+2⋅nums[2]+...+(n−1)⋅nums[n−1]
代码实现
根据题目分析,显然我们可以直接写出如下代码,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public: int maxRotateFunction(vector<int>& nums) { int n = nums.size(); int S = 0; int F0 = 0; for(int i=0;i<n;i++){ S+=nums[i]; F0 += i * nums[i]; } vector<int> F(n); F[0] = F0; int maxF = F0; for(int k=1;k<n;k++) { F[k] = F[k-1]+S-n*nums[n-k]; maxF = max(maxF, F[k]); } return maxF; } };
|
时间复杂度: O(n)
空间复杂度: O(n)
由于下一步的状态转移只依赖了前一个状态,故空间复杂度可使用滚动数组优化如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public: int maxRotateFunction(vector<int>& nums) { int n = nums.size(); int S = 0; int F0 = 0; for(int i=0;i<n;i++){ S+=nums[i]; F0 += i * nums[i]; } int F[2]; F[0] = F0; int maxF = F0; for(int k=1;k<n;k++) { F[k % 2] = F[(k-1) % 2]+S-n*nums[n-k]; maxF = max(maxF, F[k % 2]); } return maxF; } };
|
时间复杂度: O(n)
空间复杂度: O(1)