1838.最高频元素的频数
难度:中等
题目
元素的 频数 是该元素在一个数组中出现的次数。
给你一个整数数组 nums 和一个整数 k 。在一步操作中,你可以选择 nums 的一个下标,并将该下标对应元素的值增加 1 。
执行最多 k 次操作后,返回数组中最高频元素的 最大可能频数 。
提示:
- 1 <= nums.length <= 10^5
- 1 <= nums[i] <= 10^5
- 1 <= k <= 10^5
示例
示例 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
分析
脑回路是这样的...
刚开始,这题有点难,嗯用例范围10^5,放弃多重循环的暴力吧.
看到示例3,没毛病不管会不会,至少先排个序吧。
在瞅示例1吧,前缀和,貌似也不对?拿[1, 2, 4]来说,1-2是1,2-4是2,那1-4不是还要加一次2。还要加一次?
那不就是每次右移一位,需要增加(right - left) * (nums[right] - nums[right -1])
这么多数字。
那如果pre_sum不够了,收缩下呢?就是nums[right] - nums[left]
吧。好了,想到这里解题基本就成型了。
我们使用一个滑动窗口模板,默认窗口拉伸,当pre_sum > k时,收缩左边界。直至满足条件,然后每次计算最大窗口距离:
# 滑动窗口模板
left,right = 0, (0 or 1)
ret = total = 0
while right < len(nums):
更新total值
while 窗口内数据不满足要求
1. 更新total值
2. 收缩左边界
更新ret最大值
返回 ret
解题
class Solution:
def maxFrequency(self, nums: List[int], k: int) -> int:
nums.sort()
left, right, pre_sum, ret = 0, 1, 0, 1
while right < len(nums):
pre_sum += (right - left) * (nums[right] - nums[right - 1])
while pre_sum > k:
pre_sum -= nums[right] - nums[left]
left += 1
ret = max(ret, right - left + 1)
right += 1
return ret
欢迎关注我的公众号: 清风Python,带你每日学习Python算法刷题的同时,了解更多python小知识。
我的个人博客:https://qingfengpython.cn