5. leetCode--697数组的度

1. leetCode–697数组的度

1.1 问题描述
  1. 给定一个非空且只包含非负数的整数数组 nums,

  2. 数组的度的定义是指数组里任一元素出现频数的最大值。

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

  4. 示例 1:

    输入: [1, 2, 2, 3, 1]
    输出: 2
    解释:
    输入数组的度是2,因为元素12的出现频数最大,均为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.
    
  5. 示例 2:

    输入: [1,2,2,3,1,4,2]
    输出: 6
    
  6. 注意:

    nums.length 在150,000区间范围内。
    nums[i] 是一个在049,999范围内的整数。
    
1.2 问题分析
  1. 利用HashMap把我们需要的三种数据进行封装:
    1. 用来存放nums数组中每个数出现的次数countMap
      • **countMap.getOrDefault(key,defaulValue)**当Map集合中有这个key时,就使用这个key值,如果没有就使用默认值defaultValue
    2. 每个value用来存放首次出现的位置 keyFirst
    3. 每个value末尾出现的位置 keyLast
  2. 然后获得该数组的度arrDegree
  3. 最后遍历数组,找到countMapkey对应value==arrDegree的key通过keyFirstkeyLast找到最终的result。
1.3 代码实现
 public static int findShortestSubArray(int[] nums) {

        // 用来存放nums数组中每个数出现的次数
        Map<Integer,Integer> countMap = new HashMap<>();
        // 每个value首次出现的位置
        Map<Integer,Integer> keyFirst = new HashMap<>();
        // 每个value末尾出现的位置
        Map<Integer,Integer> keyLast = new HashMap<>();

        // 遍历数组
        for (int i = 0; i < nums.length; i++) {
            int temp = nums[i];

            // 如果countMap中不存在temp,value=1;
            // 如果countMap中存在temp,value = value + 1;
            countMap.put(temp,countMap.getOrDefault(temp,0)+1);

            // 遍历到最后就变成了每个数字的最后一位的下标
            keyLast.put(temp,i);

            // 每个数字的第一位的下标
            if(!keyFirst.containsKey(temp)){
                keyFirst.put(temp,i);
            }
        }

        // 得到该数组的度--遍历countMap得到
        int arrDegree = 0;

        for (int i = 0; i < nums.length; i++) {
            arrDegree = Math.max(arrDegree, countMap.get(nums[i]));
        }

        // 遍历数组
        int result = nums.length;

        for (int i = 0; i < nums.length; i++) {
            int temp = nums[i];
            int count = countMap.get(temp);
            // 不满足的值
            if (count != arrDegree) {
                continue;
            }
            result = Math.min(result, keyLast.get(temp) - keyFirst.get(temp) + 1);
         }
     
        return result;
    }
1.4 测试代码
/**
 * @Date 2020/5/14 17:33
 * @Version 10.21
 * @Author DuanChaojie
 */
public class FindShortestSubArray {
    public static void main(String[] args) {
        int[] nums = new int[]{1,2,2,3,1,8};
        int shortestSubArray = findShortestSubArray(nums);
        System.out.println("shortestSubArray = " + shortestSubArray);
    }
}

1.5 结果分析

执行结果:

  1. 执行用时 :25 ms, 在所有 Java 提交中击败了83.62%的用户
  2. 内存消耗 :42.7 MB, 在所有 Java 提交中击败了6.25%的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值