给定一个非空且只包含非负数的整数数组 nums
, 数组的度的定义是指数组里任一元素出现频数的最大值。
你的任务是找到与 nums
拥有相同大小的度的最短连续子数组,返回其长度。
示例 1:
输入: [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:
输入: [1,2,2,3,1,4,2] 输出: 6
注意:
nums.length
在1到50,000区间范围内。nums[i]
是一个在0到49,999范围内的整数。
import sys
class Solution:
def findShortestSubArray(self, nums: 'List[int]') -> 'int':
# 统计每个num的次数
dic = {}
for num in nums:
if num in dic:
dic[num] += 1
else:
dic[num] = 1
#找到度
degree = max(dic.values())
# 找到众数
mode = []
for key, value in dic.items():
if value == degree:
mode.append(key)
# 找每个众数的首尾index,取最短
max_len = len(nums)
for m in mode:
temp_len = (len(nums) - nums[::-1].index(m)) - nums.index(m)
#print(m,':', nums.index(m),',', len(nums)-nums[::-1].index(m)-1)
max_len = min(temp_len, max_len)
return max_len
def findShortestSubArray2(self, nums: 'List[int]') -> 'int':
max_len = sys.maxsize
degree = 0
dic = {}
startIdx = {}
for i in range(len(nums)):
if nums[i] in dic: # 统计每个num的次数
dic[nums[i]] += 1
else:
dic[nums[i]] = 1
if nums[i] not in startIdx: # 统计每个num 第一次出现的位置
startIdx[nums[i]] = i
if dic[nums[i]] == degree: # 如果num次数等于度数,则取最短子数组长度
max_len = min(max_len, i-startIdx[nums[i]]+1)
elif dic[nums[i]] > degree: # 如果num次数大于当前度数,则更新数组的度
max_len = i - startIdx[nums[i]] + 1
degree = dic[nums[i]]
return max_len
if __name__ == '__main__':
s = Solution()
# nums = [2, 2, 2, 2, 2]
# nums = [1,3,5,4,7]
nums = [1, 2, 2, 3, 1]
print(s.findShortestSubArray2(nums))