标签:元素 697 degree nums counter 力扣 次数 数组
给定一个非空且只包含非负数的整数数组 nums,数组的 度 的定义是指数组里任一元素出现频数的最大值。
你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。
示例1:
输入:nums = [1,2,2,3,1]
输出:2
解释:
输入数组的度是 2 ,因为元素 1 和 2 的出现频数最大,均为 2 。
连续子数组里面拥有相同度的有如下所示:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
最短连续子数组 [2, 2] 的长度为 2 ,所以返回 2 。
示例2:
输入:nums = [1,2,2,3,1,4,2]
输出:6
解释:
数组的度是 3 ,因为元素 2 重复出现 3 次。
所以 [2,2,3,1,4,2] 是最短子数组,因此返回 6。
解题思路@负雪明烛
- 先求原数组的度
求数组的度,本质还是求各个元素的出现次数,我们可以用 字典(哈希表)计数,字典的 key 是元素,value 是该元素出现的次数。因此,字典中所有 value 的最大值就是数组的度 degree。 - 再求与原数组相同度的最短子数组
- 要求的子数组的度与原数组相同度的相同,那么该子数组中也得有 degree 个重复的元素。比如对于示例二[1,2,2,3,1,4,2],出现次数最多的元素是 2,它的出现次数为 3, 所以数组的度为 3;我们要求的子数组得有 3 个 2 ,所以最短的子数组是 [2,2,3,1,4,2]。注意到了吗?我们要求的最短子数组的起始和终止位置,由出现次数最多的元素 第一次和最后一次出现的位置 确定。
- 另外,需要注意的是出现次数最多的元素可能不止一个,比如示例一[1, 2, 2, 3, 1],数字 1 和数字 2 都出现了 2 次。此时,我们必须分别对每个出现次数为 2 的元素(即数字 1 和数字 2 )都求一次包含2个它的最短子数组的长度(分别为5和2),最终对所有最短子数组长度取 min,得到结果为 2。
使用
left
和right
分别保存每个元素在数组中第一次出现的位置和最后一次出现的位置;使用counter
保存每个元素出现的次数。
数组的度 degree 等于counter.values()
的最大值;
对counter
再次遍历:如果元素 k 出现的次数等于 degree,则找出元素 k 最后一次出现的位置 和 第一次出现的位置,计算两者之差+1,即为子数组长度。
对所有出现次数等于 degree 的子数组的最短长度,取 min。
class Solution:
def findShortestSubArray(self, nums: List[int]) -> int:
left, right = dict(), dict()
counter = collections.Counter()
for i, num in enumerate(nums):
if num not in left:
left[num] = i
right[num] = i
counter[num] += 1
degree = max(counter.values())
res = len(nums)
for k, v in counter.items():
if v == degree:
res = min(res, right[k] - left[k] + 1)
return res
时间复杂度:O(N),因为对数组遍历了一遍,对counter 遍历了两遍。
空间复杂度:O(N),因为 counter 在最坏情况下会跟 nums 的元素个数相等。
作者:fuxuemingzhu
链接:https://leetcode-cn.com/problems/degree-of-an-array/solution/xiang-xi-fen-xi-ti-yi-yu-si-lu-jian-ji-d-nvdy/
标签:元素,697,degree,nums,counter,力扣,次数,数组 来源: https://www.cnblogs.com/Jojo-L/p/16057978.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。