本题不是纯粹的差分数组,只不过使用差分数组解决更快。
设一个数组res,其中res[x]表示的是,nums[i] + nums[n - 1 - i] 为 x 的时候,需要多少次操作。所以这题就抽象成计算出所有的x中最小的res[x]即可。关键是,如何求出每一个 res[x] 位置的值,需要多少操作?为了叙述方便,假设 nums[i] 为 A,nums[n - 1 - i] 为 B,最终的 A+B 为 C。
先假设res中所有数都是2,即都需要2次操作,然后在这上面进行筛选,注意这里的“所有数”表示范围[2, 2 * limit],因为nums[i] + nums[n - 1 - i] 最小是 2,即将两个数都修改为 1;最大是 2 * limit,即将两个数都修改成 limit
首先在区间[1 + min(A, B), limit + max(A, B)]中,res肯定都是1。这个区间表示的是某一个 A+B 的范围,A+B如果要等于这个区间中的一个数,只要修改一个A、B中的一个即可。
其次在[A + B]这个位置也要减1,很容易理解嘛,因为A和B要算出A+B根本不需要修改。
最后利用差分数组的方法求res中最小的一个。
class Solution {
public:
int minMoves(vector<int>& nums, int limit) {
vector<int> diff(2 * limit + 2, 0);
int n = nums.size();
for (int i = 0; i < n / 2; i++)
{
int A = nums[i], B = nums[n - 1 - i];
//首先在区间[2, 2 * limit]中都是2
int l = 2, r = 2 * limit;
diff[l] += 2;
diff[r + 1] -= 2;
//在区间[1 + min(A, B), limit + max(A, B)]的都减去1
l = 1 + min(A, B), r = limit + max(A, B);
diff[l] += -1;
diff[r + 1] -= -1;
//用差分数组的方式把A+B的位置减去1
l = A + B, r = A + B;
diff[l] += -1;
diff[r + 1] -= -1;
}
int ans = n, sum = 0;
for (int i = 2; i < 2 * limit + 1; i++)
{
sum += diff[i];
if (sum < ans)
ans = sum;
}
return ans;
}
};