2602. 使数组元素全部相等的最少操作次数
方法:排序 + 前缀和 + 二分查找
解题思路
- 初始化\(target = queries[i]\),根据题意,对于每次询问要将数组\(nums\)中的元素\(=>target\),那么对于小于等于\(target\)的元素要加上一个数,而大于\(target\)的元素则要减去一个数,那么可以见得\(target\)可以将数组分为两部分;
- 因此可以将\(nums\)数组从小到大排序,然后就可以利用二分查找确定\(target\)的位置,对于小于等于\(target\)的部分\([0, idx]\),其操作次数为\(target * (idx + 1) - sum(nums[0, idx])\),对于大于\(target\)的部分\([idx + 1, n - 1]\),其操作次数为\(sum(nums[idx + 1, n - 1]) - target * (idx + 1)\),注意其中的\(sum\)可以利用前缀和来简化计算。
代码
class Solution {
public:
vector<long long> minOperations(vector<int>& nums, vector<int>& queries) {
sort(nums.begin(), nums.end()); // 排序
int n = nums.size(), m = queries.size();
vector<long long> s(n + 1), ans(m);
for (int i = 1; i <= n; i ++ ) s[i] = s[i - 1] + nums[i - 1]; // 前缀和计算
for (int i = 0; i < m; i ++ ) {
long long target = queries[i], cnt = 0;
int idx = upper_bound(nums.begin(), nums.end(), target) - nums.begin(); // 查找idx
cnt += target * idx - s[idx];
cnt += s[n] - s[idx] - target * (n - idx);
ans[i] = cnt;
}
return ans;
}
};
复杂度分析
时间复杂度:\(O((q + n)logn),其中q为queries数组的长度\);
空间复杂度:\(O(n)\)。

浙公网安备 33010602011771号