一、 题目
1. 题目描述
元素的 频数 是该元素在一个数组中出现的次数。
给你一个整数数组 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 <= 105
1 <= nums[i] <= 105
1 <= k <= 105
Related Topics
- 数组
- 二分查找
- 前缀和
- 滑动窗口
- 👍 225
- 👎 0
2. 原题链接
链接: 1838. 最高频元素的频数
二、 解题报告
1. 思路分析
1.把每个数想象成柱状图,问题转化为,用最多k个格子,填一部分柱子,使这部分柱子等高,满足的话更新宽度。
2.排完序更好想。
3.那么实际上是求做上方三角形面积,用长方形-柱状图面积:s=r*(r-l+1)-sum_interval(l,r),需求s<=k,可以双指针。
4.按这个思路不用前缀和,直接排序+滑窗也可以。
2. 复杂度分析
最坏时间复杂度O(n)
3. 代码实现
前缀和
。
class Solution:
def maxFrequency(self, nums: List[int], k: int) -> int:
nums.sort()
n = len(nums)
presum = list(accumulate(nums,initial=0))
def sum_interval(i,j):
return presum[j+1]-presum[i]
def calc_s(i,j):
return nums[j]*(j-i+1)-sum_interval(i,j)
ans = 1
l=r=0
while l<n and r<n:
s = calc_s(l,r)
if s <= k:
ans = max(ans,r-l+1)
r += 1
else:
l += 1
if l==r:
r += 1
return ans
"""
1.把每个数想象成柱状图,问题转化为,用最多k个格子,填一部分柱子,使这部分柱子等高,满足的话更新宽度。
2.排完序更好想。
3.那么实际上是求做上方三角形面积,用长方形-柱状图面积:s=r*(r-l+1)-sum_interval(l,r),需求s<=k,可以双指针。
4.按这个思路不用前缀和,直接排序+滑窗也可以。
"""
三、 本题小结
- 前缀和+双指针的应用。