最多K次重复元素的最长子数组-LeetCode
2958. 最多 K 次重复元素的最长子数组
🎯 问题描述(来源于LeetCode)
描述:
给你一个整数数组 nums 和一个整数 k。
如果一个子数组中每个元素的出现次数都不超过 k 次,我们就称这个子数组是好子数组。
请你返回 nums 中最长好子数组的长度。
说明:
-
这是一个不定长滑动窗口问题。
-
核心逻辑是维护一个窗口,使得窗口内任意元素的出现次数都不超过 k 次。
-
当某个元素的出现次数超过
k时,收缩左边界。 -
示例:
-
示例 1:
1 | 输入:nums = [1,2,3,1,2,3,1,2], k = 2 |
- 示例 2:
1 | 输入:nums = [1,2,1,2,1,2,1,2], k = 1 |
💻 解题思路
思路1:不定长滑动窗口
思路1:代码实现
1 | class Solution: |
思路1:📊 性能分析
- 时间复杂度:
- 其中 是数组
nums的长度。 - 虽然代码中有一个
while循环嵌套在for循环中,但每个元素最多被访问两次(一次被右边界right加入,一次被左边界left移出)。因此,整体操作次数是线性的。
- 其中 是数组
- 空间复杂度:
- 哈希表
count在最坏情况下(数组所有元素都不同)需要存储 个键值对。
- 哈希表
思考
-
通用模板:
- 这道题是“无重复字符的最长子串”(k=1)和“水果成篮”(每个篮子无限容量,但种类限制为2,略有不同)的变体。
- 更准确地说,它是“每个字符最多出现 k 次”的通用版本。
- 代码逻辑非常简洁,只需将判断条件设为
count[num] > k即可。
-
收缩逻辑:
while count[num] > k:保证了窗口的合法性。- 当某个数字
num的出现次数超过k时,我们不断移除左边的元素,直到num的次数降回k。
-
不需要删除键:
- 与之前的题目一样,这里也不需要
del count[nums[left]]。 - 因为
Counter允许值为 0 的键存在,且判断条件只关心是否大于k。
- 与之前的题目一样,这里也不需要
-
结果更新:
result = max(result, right - left + 1)放在while循环之后。- 确保只有在窗口合法(所有元素出现次数 <= k)时,才更新最大长度。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






