2021年2月20日 Leetcode每日一题:697. 数组的度

数组的度

1.题目描述

给定一个非空且只包含非负数的整数数组 nums,数组的度的定义是指数组里任一元素出现频数的最大值。

你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。

2.示例

示例 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

3.读题

这一题又定义了一个新的概念:数组的度。
那么,数组的度是什么呢?数组的度的定义是指数组里任一元素出现频数的最大值。题目给出的定义有一些许的抽象,结合示例来看更好理解。
其实,数组的度是这样得出的:

1.数组中有许多不同的数字,也可能会出现数字的重复。而每个数字在数组中重复的次数,就是它在数组中出现的频数
2.数组中所有数字都会有一个频数,而所有数字的频数中的最大值,就是数组的度。

4.思路

这一题要求的是,与原数组有着相同的度的最短连续子数组的长度。
事实上,由于数组的度本质上只和出现频度最高的数字(可能是一个也可能有多个不同数字)有关,因此,我们需要找出的这个连续子数组,它只需要完整地包含出现频度最高的数字中的某一个。
由于我们需要找出的是符合该条件的最短连续子数组,因此当该子数组完整地包含某一个出现数字时,该子数组的开头即为该数字第一次出现的位置,该子数组的结尾即为该数字最后一次出现的位置,这样既可让该连续子数组在完整地包含某一个数字的前提下达到最短。
所以,我们找出数组中每一个出现次数为数组的度的数字,以及其开头和结尾的位置。那么,其开头和结尾相距最短的那一组数字,从该开头到该结尾的连续子数组,就是我们要求的与原数组拥有相同大小的度的最短连续子数组。
使用HashMap来记录我们所需的信息,HashMap的键为数组中的数字,值为一个三元数组,其中数组的第一个值是该数字出现的频数,第二个值是该数字第一次在数组中出现的位置,第三个值是该数字在数组中最后一次出现的位置。
那么,我们首先遍历一次原数组,即可找出原数组的度以及数组中每一个元素第一次和最后一次出现的位置。
然后,再遍历一遍HashMap的键,即数组中出现的数字。仅当该数字出现的次数等于原数组的度时,我们采用其(最后一次出现的位置-第一次出现的位置+1)作为度与原数组相同的连续子数组的长度的一个极小值,与全局最小值进行比较。
当然,由于题目中限定了原数组中数字的范围在0~49999,因此也可以用三个长度为50000的数组作为字典,其他思路同上。

5.代码

class Solution {
    public int findShortestSubArray(int[] nums) {
        Map<Integer,int[]> map = new HashMap<>();
        int max = 0;
        for(int i=0;i<nums.length;i++){
            int a = nums[i];
            if(map.containsKey(a)){
                map.get(a)[0]++;
                map.get(a)[2]=i;
            }else{
                map.put(a,new int[3]);
                map.get(a)[0]=1;
                map.get(a)[2]=i;
                map.get(a)[1]=i;
            }
            max = Math.max(max,map.get(a)[0]);
        }
        int min = Integer.MAX_VALUE;
        for(int key:map.keySet()){
            int[] s = map.get(key);
            if(s[0]==max){
                min = Math.min(min,s[2]-s[1]+1);
            }
        }
        return min;
    }
}

你可能感兴趣的:(leetcode每日一题,leetcode,java,算法)