力扣2968.执行操作使频率分数最大
方法一:滑窗 + 前缀和
-
求前缀和数组s
-
求一个数组补齐到中位数的差值
- 枚举右端点
-
class Solution { public: int maxFrequencyScore(vector<int>& nums, long long k) { int res=0,n = nums.size(); sort(nums.begin(),nums.end()); vector<long long> s(n + 1, 0); for (int i = 0; i < n; i++) { s[i + 1] = s[i] + nums[i]; } auto distance_sum = [&](int l, int i, int r) -> long long { long long left = (long long) nums[i] * (i - l) - (s[i] - s[l]); long long right = s[r + 1] - s[i + 1] - (long long) nums[i] * (r - i); return left + right; }; for(int i=0,j=0;i<n;i++) { while(distance_sum(j,(i+j)/2,i) > k) j ++; res = max(res,i-j+1); } return res; } };
方法二:滑窗 + 贡献法
-
考虑每个元素对答案的贡献
-
发现每枚举到一个数时 + nums[i] – nums[i + j / 2]
-
同理 当left++时为 + nums[j] - nums[(i+j+1)/2]
-
class Solution { public: int maxFrequencyScore(vector<int>& nums, long long k) { int res=0,n = nums.size(); long long s = 0; sort(nums.begin(),nums.end()); for(int i=0,j=0;i<n;i++) { s += nums[i] - nums[(i+j)/2]; while(s > k) { s += nums[j++] - nums[(i+j)/2]; } res = max(res,i-j+1); } return res; } };