chenfy27的刷题记录

导航

leetcode2968 执行操作使频率分数最大

给定长度为n的数组nums和整数k,可以对数组执行至多k次操作,每次选择1个nums[i],将其增加或减少1,最终数组的频率分数定义为数组众数的频率,求可以得到的最大频率分数。
1<=n<=1E5; 1<=nums[i]<=1E9; 0<=k<=1E14

分析:
(1)中位数贪心:对于有序数组,如果所有元素都变成相同的数,最优做法是全部变成中位数。如果个数为偶数,则变成中间两数或者该两数之间任意整数,结果是一样的。
(2)前缀和快速求和,前半部分是负的,后半部分是正的,分开算。
(3)对原数组排序,然后滑动窗口维护可行的子数组,更新答案。

class Solution {
public:
    int maxFrequencyScore(vector<int>& nums, long long k) {
        std::sort(nums.begin(), nums.end());
        int n = nums.size();
        std::vector<long long> pre(n);
        pre[0] = nums[0];
        for (int i = 1; i < n; i++) {
            pre[i] = pre[i - 1] + nums[i];
        }
        auto sum = [&](int l, int r) {
            l = std::max(l, 0);
            r = std::min(r, n - 1);
            return l ? pre[r] - pre[l - 1] : pre[r];
        };
        auto get = [&](int l, int r) {
            int m = (l + r) / 2;
            int L = m - l + 1;
            int R = r - m;
            return 1LL * (L - R) * nums[m] - sum(l, m) + sum(m + 1, r);
        };
        int ans = 0;
        for (int l = 0, r = 0; r < n; r++) {
            while (get(l, r) > k) {
                l += 1;
            }
            ans = std::max(ans, r - l + 1);
        }
        return ans;
    }
};

posted on 2024-12-04 22:00  chenfy27  阅读(3)  评论(0编辑  收藏  举报