元素的 频数 是该元素在一个数组中出现的次数。
给你一个整数数组 nums 和一个整数 k 。在一步操作中,你可以选择 nums 的一个下标,并将该下标对应元素的值增加 1 。
执行最多 k 次操作后,返回数组中最高频元素的 最大可能频数 。
示例 1:
输入:nums = [1,2,4], k = 5
输出:3
解释:对第一个元素执行 3 次递增操作,对第二个元素执 2 次递增操作,此时 nums = [4,4,4] 。
4 是数组中最高频元素,频数是 3 。
示例 2:
输入:nums = [1,4,8,13], k = 5
输出:2
解释:存在多种最优解决方案:
- 对第一个元素执行 3 次递增操作,此时 nums = [4,4,8,13] 。4 是数组中最高频元素,频数是 2 。
- 对第二个元素执行 4 次递增操作,此时 nums = [1,8,8,13] 。8 是数组中最高频元素,频数是 2 。
- 对第三个元素执行 5 次递增操作,此时 nums = [1,4,13,13] 。13 是数组中最高频元素,频数是 2 。
示例 3:
输入:nums = [3,9,6], k = 2
输出:1
提示:
1 <= nums.length <= 10^51 <= nums[i] <= 10^51 <= k <= 10^5
class Solution {
public int maxFrequency(int[] nums, int k) {
//看起来频数跟顺序毫无关系,我直接一个排序
Arrays.sort(nums);
//理解题意:肯定存在一个公式能满足滑动窗口,现在就是要想出来公式是什么?
// 公式:依次像右移动. 关键点在于元素之间的差值的和,如果,超出1个间隔,则需要 * (l 和 r的间值) ,不能超过K.
// 如果差值超出了K,则l向由移动,然后差值.减去.
int length = nums.length;
//左指针
int l = 0;
//
long total = 0;
int result = 1;
for(int r = 1 ; r < length ; r++){
//总数值 = 总数值 + 移后一位和前一位的差值,并且给l 到 r之前都增加这个差值
total = total + (long) (nums[r] - nums[r-1]) * (r-l);
while(total > k){
//总数值 = 总数值 + r 和 l 的差值.
total = total - (nums[r] - nums[l]) ;
l++;
}
result = Math.max(result,r - l + 1);
}
return result;
// // 这是一个错误的题解:为什么我要把他保留下来,因为我感觉这破题目真是考语文的.
// /**
// 明确点:“执行最多 k 次操作后” 这里指的是:从l 到 r 其中的每一次加+1都应该被算在内.!!!!
// // 例如:[1,2,4,7]
// //通过这个算法题解为:4,但是答案实际上为3
// */
// // int r = 0;
// //当第一个数字+k.得到一个值,索引r 判断他能到哪个值.然后依次向后累加,啥时候累加发现 value > r
// // 计算长度,
// // left +1 ; r = l //开启下一次循环
// for(int l= 0; l < nums.length; l++){
// int r = l;
// int temp = nums[l] + k;
// while(r < nums.length && nums[r] <= temp){
// result = Math.max(result,r - l + 1);
// r++;
// }
// }
// return result;
}
}