题目说明
给定一个非空且只包含非负数的整数数组 nums,数组的度的定义是指数组里任一元素出现频数的最大值。
你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。
nums.length 在1到 50,000 区间范围内。
nums[i] 是一个在 0 到 49,999 范围内的整数。
示例
例1
1 2 3 4 5 6 7
| 输入:[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 3 4 5
| 输入:[1,2,2,3,1,4,2] 输出:6 解释: 输入数组的度是3,元素2的出现频数最大,为3. 最短连续子数组[2,2,3,1,4,2]的长度为6,所以返回6.
|
笔者理解
此题是一道数组算法问题,在力扣题库中被定义为简单题。
解法
当笔者阅读完此题后,发现此题运用哈希表再合适不过了,用哈希表来计算各元素出现的次数,存储各元素出现的首次及末次的位置,让我们来看看具体如何实现的吧。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| public int findShortestSubArray(int[] nums) { if(nums.length==1){ return 1;} if(nums.length==2){
if(nums[0]==nums[1]){ return 2;} else{ return 1;} } HashMap <Integer,Integer>hashMap = new <Integer,Integer>HashMap();
HashMap <Integer,Integer>front = new <Integer,Integer>HashMap();
HashMap <Integer,Integer>rear = new <Integer,Integer>HashMap(); int result = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) { hashMap.put(nums[i],hashMap.getOrDefault(nums[i],0)+1);
if(front.get(nums[i])==null){ front.put(nums[i],i);}
rear.put(nums[i],i); } int maxTimes = 0; for(Integer key : hashMap.keySet()){ maxTimes = Math.max(maxTimes,hashMap.get(key)); } for(Integer key : hashMap.keySet()){ if(hashMap.get(key)==maxTimes){ result = Math.min(result,rear.get(key)-front.get(key)+1); } } return result; }
|
时间和空间效率都较高,可见此解法比较适合此题;

总结
本题是今天的每日一题,难度是简单,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。