LeetCode697-数组的度
给定一个非空且只包含非负数的整数数组 nums,数组的度的定义是指数组里任一元素出现频数的最大值。
你的任务是在 nums 中找到与 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.
分析思路:
通过分治原理,将题目拆解,可得题目有两个考点,第一个就是找到数组里面出现频数最大的值,例如
[10,10,20] 出现最多的值就是10 出现了2次,这出现了几次,也就是这个数组的度
[10,10,20,20] 出现最多的值就是10和20 出现了2次,2也就是这个数组的度
第二个就是返回与这个数组拥有相同大小的度的最短连续子数组的长度
通过思考可得,
- 如果一个数组里面度==1,那么它的最短连续子数组的长度就是1
- 如果一个数组里面的度>1,并且得到这个度的频数是唯一的,那么就是出现出现最多次的那个数字的首尾下标相减+1
- 如果一个数组里面的度>1,并且这个度的频数不唯一,则取首尾下标相减+1最小的那个值.
那么我们可以重新构造一种数据结构,用来保存当前这个值,以及首尾下标,以及这个值出现的次数,和首尾下标的距离
class struct {
int num;//这个数据结构代表的值
int count;//这个值出现的次数
int headIndex;//首次出现该值的下标
int tailIndex;//最后一次出现该值的下标
int distance;//首尾下标的距离
public struct(int num){
this.num = num;
}
}
public static int findShortestSubArray(int[] nums) {
//使用一个Map来存放对应关系,一个值存放一个struct
Map<Integer, struct> map = new HashMap<>();
int count = 1;//一个数组只要不为空,必然出现一次,所以是1
int minDistance = 1;//只要出现了一次,那么最小距离必然是1
for(int i = 0; i < nums.length; i++){
if(map.containsKey(nums[i])){
struct struct = map.get(nums[i]);
struct.tailIndex = i;
struct.distance = struct.tailIndex - struct.headIndex + 1;
struct.count++;
if(struct.count == count && struct.distance < minDistance){
minDistance = struct.distance;
}else if(struct.count > count){
count = struct.count;
minDistance = struct.distance;
}
}else{
struct struct =new struct(nums[i]);
struct.headIndex = i;
struct.tailIndex = i;
struct.distance = 1;
struct.count = 1;
map.put(nums[i], struct);
}
}
return minDistance;
}

浙公网安备 33010602011771号