题目
思路 差分数组
计算数组中每一个元素可以得分的轮调下标区间,由于是区间,可以用差分数组只需要保存起始端点,最后计算前缀和,得出最大的前缀和对应的下标。计算轮调区间:原下标是i,改变后的下标是(i + n - k) mod n,范围是[0,n - 1]。要使轮调后得分:(i + n - k) mod n <= nums[i]。经整理计算后,k需要满足的条件是(i + 1) mod n <= k && k <= (i + n - nums[i]) mod n。把i当作变量,在数轴上表示出区间,可以得出:a = (i + 1) mod n,b = (i + n - nums[i])。a <= b时,k取[a,b];a > b时,k取[0, b]和[a, n - 1]。
代码
class Solution {
public:
vector<int> c;
void add(int l, int r){
c[l] += 1;
c[r + 1] -= 1;
}
int bestRotation(vector<int>& nums) {
int n = nums.size();
c.resize(n + 1);
for(int i = 0; i < n; i++){
int a = (i + 1) % n, b = (i + n - nums[i]) % n;
cout<<a<<' '<<b<<endl;
if(a <= b)
add(a, b);
else{
add(0, b);
add(a, n - 1);
}
}
int ans = 0;
for(int i = 1; i <= n; i++){
c[i] += c[i - 1];
if(c[ans] < c[i])
ans = i;
}
return ans;
}
};