一、问题描述
给你一个整数数组 nums
和一个整数 k
。
在一步操作中,你可以选择 nums
的一个下标,并将该下标对应元素的值增加 1
。
执行操作数最多为 k
次,返回数组中最高频元素的 最大可能频数。
(最高频元素不唯一,但整个数组的最大频数唯一。)
二、测试数据
示例 1:
输入:nums = [1,2,4], k = 5
输出:3
解释:对第一个元素 1 进行 3 次递增操作(1+3 = 4),对第二个元素 2 进行 2 次递增操作(2+2 = 4),最后 nums = [4,4,4] 。
最高频元素是 4 ,频数是 3 。
示例 2:
输入:nums = [1,4,8,13], k = 5
输出:2
解释:存在多种最优解决方案:
- 对第一个元素 1 进行 3 次递增操作,最后 nums = [4,4,8,13] 。最高频元素是 4,频数是 2 。
- 对第二个元素 4 进行 4 次递增操作,最后 nums = [1,8,8,13] 。最高频元素是 8,频数是 2 。
- 对第三个元素 8 进行 5 次递增操作,最后 nums = [1,4,13,13] 。最高频元素是 13,频数是 2 。
示例 3:
输入:nums = [3,9,6], k = 2
输出:1
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 105
1 <= k <= 105
三、解题思路
利用 排序 + 滑动窗口
- 1、先将数组排序
- 2、找到符合条件的最大滑动窗口
- 遍历数组,从位序为 0 的数字开始。
- 在符合条件(增加的数值小于
k
)下扩大窗口right++
( 整个滑动窗口nums[left] ~~ nums[right]
维持的都是相同的数 :nums[right]
) - 不符合条件的情况下,缩小窗口
left++
,恢复total
值total -= nums[right] - nums[left]
(总共增加的数值)
- 在符合条件(增加的数值小于
- 遍历数组,从位序为 0 的数字开始。
- 3、最大频数为最终窗口的大小
四、java实现
class Solution {
public int maxFrequency(int[] nums, int k) {
int length = nums.length;
Arrays.sort(nums);
int total = 0;
int count = 1;//默认为 1 (length 最小为 1)
for(int left = 0,right = 1;right<length;right++){
total += (nums[right]-nums[right-1])*(right-left); //total 为增加的数值
while(total > k){ //若增加的数值大于 k
total -= nums[right] - nums[left++]; //缩小窗口,恢复对应的 total 值
}
count = Math.max(count,right-left+1);//最大频数为窗口大小
}
return count;
}
}