数据按排序后,处于中间位置的数值(数据个数奇数取正中间,偶数取中间两个的平均值)

lc462
class Solution {
public:
int minMoves2(vector<int>& nums) {
int m = nums.size() / 2;
++ranges::nth_element(nums, nums.begin() + m);++
++int mid = nums[m];++
int ans = 0;
for (int x : nums) {
++ans += abs(x - mid);++
}
return ans;
}
};
lc2033
class Solution {
/*
输入:grid = [[2,4],[6,8]], x = 2
输出:4
*/
public:
int minOperations(vector<vector<int>>& grid, int x)
{
vector<int> a;
for(auto& g:grid)
{
for(auto& e:g)
a.push_back(e);
}
int n=a.size();
int m=n/2;
++ranges::nth_element(a,a.begin()+m);
int mid=a[m];++
int ret=0;
for(auto& b:a)
{
int d=abs(b-mid);
if(d%x!=0)
return -1;
ret+=(d/x);
}
return ret;
}
};

lc2602
排序+前缀和+二分
++right = sum[n] - sum[j] - q * (n - j); // 绿色面积++
使数组元素 全部等于某个元素的最小操作数
从q*n优化为(q+n)*log n

class Solution {
public:
vector<long long> minOperations(vector<int>& nums, vector<int>& queries) {
ranges::sort(nums);
int n = nums.size();
vector<long long> sum(n + 1); // 前缀和
for (int i = 0; i < n; i++) {
sum[i + 1] = sum[i] + nums[i];
}
int m = queries.size();
vector<long long> ans(m);
for (int i = 0; i < m; i++) {
int q = queries[i];
long long j = ranges::lower_bound(nums, q) - nums.begin();
long long left = q * j - sum[j]; // 蓝色面积
long long ++right = sum[n] - sum[j] - q * (n - j); // 绿色面积++
ans[i] = left + right;
}
return ans;
}
};
lower_bound 返回有序容器中++第一个≥目标值的元素迭代器++
upper_bound 返回第一个>目标值的元素迭代器(均基于二分查找,仅匹配条件不同)
lc2615
hash分组+前缀和求距离和
++ret[q] = left + right;++
class Solution {
typedef long long ll;
public:
vector<long long> distance(vector<int>& nums) {
int n=nums.size();
unordered_map<int,vector<int>> hash;
vector<ll> ret(n);
for(int i=0;i<n;i++)
{
hash[nums[i]].push_back(i);
}
for(auto& [_,b]:hash)
{
int m=b.size();
if(m==1)
{
ret[b[0]]=0;
continue;
}
vector<ll> p(m+1);
for(int i=1;i<=m;i++)
p[i]=p[i-1]+b[i-1];
for(int i=0;i<m;i++)
{
int q=b[i];
ll left = (ll)q*i-p[i]; // blue
ll right = p[m] - p[i] - (ll)q * (m - i); //green
++ret[q] = left + right;++
}
}
return ret;
}
};