[更文刷题] 697. 数组的度

64 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情

一、题目描述:

697. 数组的度 - 力扣(LeetCode) (leetcode-cn.com)

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

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

示例 1:

输入:nums = [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

示例 2:

输入:nums = [1,2,2,3,1,4,2]
输出:6
解释:
数组的度是 3 ,因为元素 2 重复出现 3 次。
所以 [2,2,3,1,4,2] 是最短子数组,因此返回 6

 

提示:

  • nums.length 在 1 到 50,000 范围内。
  • nums[i] 是一个在 0 到 49,999 范围内的整数。

二、思路分析:

用map list 存每个元素出现的下标值
即 list 的长度就为这个元素出现的次数,用来求 数组 度 ,第一个下标 和 最后一个下标之差 为子串的长度。
先按 度 从大到小排, 再按 子串长度 从小大排,map 中第一个元素就是答案。

当然也可以使用 滑动窗口,此题求最短子串,和 209 长度最小的子数组 ,滑动窗口思路一致,但需要预先求出数组的度,进行比较即可。

三、AC 代码:

class Solution {
    public int findShortestSubArray(int[] nums) {
        int n = nums.length;
        if(n == 1){
            return 1;
        }

        Map<Integer,List<Integer>> map = new HashMap<>();
        for(int i=0;i<n;i++){
            List<Integer> indexList = map.getOrDefault(nums[i],new ArrayList<>());
            indexList.add(i);
            map.put(nums[i],indexList);
        }

        Set<Map.Entry<Integer,List<Integer>>> entrySet = map.entrySet();
        List<Map.Entry<Integer,List<Integer>>> list = new ArrayList<>(entrySet);
        Collections.sort(list, new Comparator<Map.Entry<Integer,List<Integer>>>(){
            @Override
            public int compare(Map.Entry<Integer,List<Integer>> o1, Map.Entry<Integer,List<Integer>> o2) {
                // 先按度升序排列
                int size1 = o1.getValue().size(), size2 = o2.getValue().size();
                if(size1 != size2){
                    return size2-size1;
                }

                // 再按子串长度从小到大排
                int len1 = o1.getValue().get(size1-1)-o1.getValue().get(0)+1;
                int len2 = o2.getValue().get(size2-1)-o2.getValue().get(0)+1;

                return len1 - len2;
            }

        });

        // list第一个元素就是答案
        int tempSize = list.get(0).getValue().size();
        return list.get(0).getValue().get(tempSize-1) - list.get(0).getValue().get(0)+1;
    }
}