版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/majichen95/article/details/82827182
给定由非负整数组成的非空数组,数组的度定义为出现频率最高的元素。
找出最短的连续子数组,并使得它和原数组有相同的度。返回该连续子数组的长度。
样例
输入: [1, 2, 2, 3, 1]
输出: 2
解释:
输入数组的度是2,1和2都出现了两次。
具有相同度的子串包括:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
其中长度最短为2。所以返回2。
注意事项
nums.length
的范围在1到50,000之间。nums[i]
是范围为0到49,999的整数。
解题思路:
用map存储每种元素出现的次数,得到最大度数。再找到最大度数元素的首位元素下标,即计算出当前最大度连续子数组的最小长度,最后选最小的长度即可。
public class Solution {
/**
* @param nums: a list of integers
* @return: return a integer
*/
public int findShortestSubArray(int[] nums) {
// write your code here
Map<Integer,Integer> map = new HashMap<>(); //key为数组中的数字,value为每种数字的度数
int maxDo = 0;//最大度的次数
int res = Integer.MAX_VALUE;//最短的连续子数组的长度
for(int num : nums){
if(map.get(num) == null)
map.put(num,1);
else
map.put(num,map.get(num)+1);
if(map.get(num) >= maxDo)
maxDo = map.get(num);
}
for(Integer key : map.keySet()){
if(map.get(key) != maxDo)
continue;
int firstIndex = 0;
int lastIndex = 0;
//定位当前最大度元素的首元素下标
for(int i=0 ; i<nums.length ; i++){
if(nums[i] == key){
firstIndex = i;
lastIndex = i;
break;
}
}
//定位当前最大度元素的尾元素下标
if(maxDo > 1){
for(int i=nums.length-1 ; i>=0 ; i--){
if(nums[i] == key){
lastIndex = i;
break;
}
}
}
int temp = lastIndex - firstIndex + 1; //当前最大度连续子数组的长度
if(temp < res)
res = temp;
}
return res;
}
}