LeetCode——1838. 最高频元素的频数

最高频元素的频数

题目

元素的 频数 是该元素在一个数组中出现的次数。

给你一个整数数组 nums 和一个整数 k 。在一步操作中,你可以选择 nums 的一个下标,并将该下标对应元素的值增加 1 。

执行最多 k 次操作后,返回数组中最高频元素的 最大可能频数 。

思路

自己是没有什么思路的,知道说应该要进行一个排序,但是不知道应该使用哪一种算法进行解决!

看了题解,总算有点点思路!
在这里插入图片描述
操作数组后,一定是将所有数字变为其中的某一个数字。提示1解释得挺清楚的,因为结果只是求最高频元素的频数,这个时候,我们统一变成一个比最大那个数。在结果看来,我们只是影响了最高频元素的大小,并不影响最高频元素的频数

提示2,优先操作距离目标值最近的元素,因为我们对数组进行了一个排序,数组一定是从小到大进行排序的,比如右边的数是5,左边的是1,中间的是3,那肯定是操作3使得3变成5的步数比操作1变成5的步数要少!
在这里插入图片描述
这里的推导要自己去推导一下,就是在原有的基础上,假设向右移动,那么就会增加总的步数,向左移动,会减少总的步数。【每次都是将某个数字左边的所有数字变为该数字】,这样子,每次拿当前频数与操作后结果的频数进行一个比较,最终可以获得将步数k利用到极致的情况下,所能够获得的最高频元素的频数!

代码

class Solution {
    public int maxFrequency(int[] nums, int k) {
        // 对数组进行一个升序排序
        Arrays.sort(nums);
        
        // 数组的长度
        int length = nums.length;

        // 需要操作的总步数,必须保证这个数小于等于k才符合条件
        long total = 0;
        // 左指针为0,右指针为1
        int l = 0;
        int ans = 1;
        for (int i= 1; i < length; ++i) 
        {
            total += (long) (nums[i] - nums[i-1]) * (i-l);
            // 当总步数大于k时,移动左指针缩小步数
            while (total > k) 
            {
                // 根据推算,不动右指针,右移左指针会减少这么多步数
                total-= nums[i]-nums[l];
                ++l;
            }
            ans = Math.max(ans,i-l + 1);
        }
        return ans;
    }
}

结果

在这里插入图片描述
结果很强,从来对滑动窗口没什么概念,今天算是见识到了滑动窗口的好处。如果使用暴力,真的浪费了巨大的计算量!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值