一、题目描述
1.题目内容
元素的频数是该元素在一个数组中出现的次数。
给你一个整数数组 nums 和一个整数 k 。在一步操作中,你可以选择 nums 的一个下标,并将该下标对应元素的值增加 1 。
执行最多 k 次操作后,返回数组中最高频元素的最大可能频数。
2.题目示例
示例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
3.提示
1 <= nums.length <= 105
1 <= nums[i] <= 105
1 <= k <= 105
二、思路
前缀和,滑动窗口。
这道题值得注意的一点是数据范围为1e5,数量也为1e5,所以理论前缀和最大值为1e10,这超过了int能够表示的范围2e9,所以要对这部分进行处理。
处理的方式有两种,一种是使用long,一种是直接使用超限元素进行计算,这里选择的是第二种。
得到前缀和之后就可以计算滑动窗口了,通过滑动窗口就可以计算出最高频元素的频数了。
三、数据结构资料
本题无需要的数据结构。
四、代码
class Solution
{
public int maxFrequency(int[] nums, int k)
{
int result = 0;
Arrays.sort(nums);
int[] sum = new int[nums.length + 1];
for(int i = 1; i < sum.length; i++)
{
sum[i] = nums[i - 1] + sum[i - 1];
}
int left = 0, right = 0;
while(right < nums.length)
{
int mid = (left + right) / 2;
if(nums[right] * (right - left + 1) - (sum[right + 1] - sum[left]) > k)
{
left++;
}
else
{
result = Math.max(result, right - left + 1);
right++;
}
}
return result;
}
}
五、复杂度分析
时间复杂度O(nlogn)
空间复杂度O(n)
执行用时 | 时间击败比例 | 内存消耗 | 内存击败比例 |
---|---|---|---|
33ms | 74% | 47.6MB | 85% |