数组的子数组中度与原数组相同的个数 Degree of an Array

问题:数组

Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any one of its elements.app

Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums.this

Example 1:spa

Input: [1, 2, 2, 3, 1]
Output: 2
Explanation: 
The input array has a degree of 2 because both elements 1 and 2 appear twice.
Of the subarrays that have the same degree:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
The shortest length is 2. So return 2.

Example 2:code

Input: [1,2,2,3,1,4,2]
Output: 6

Note:排序

  • nums.length will be between 1 and 50,000.
  • nums[i] will be an integer between 0 and 49,999.

解决:索引

【题意】给定非空非负整数数组,数组的度是指数组中出现次数最多元素的个数。寻找最小连续子数组,使得子数组的度与原数组的度相同。返回子数组的长度element

①  使用三个map --- starts,ends,counts:get

  • ends记录元素的最大下标,starts记录元素的最小下标,counts记录元素的出现个数,三者均是HashMap结构;
  • 经过遍历记录元素与上三个对应的记录,只要找到最大次数对应的元素,则就找到了该元素的最大和最小下标,即找到了度相同的最小子数组。

 class Solution { //68ms
    public int findShortestSubArray(int[] nums) {
        Map<Integer,Integer> starts = new HashMap<>();
        Map<Integer,Integer> ends = new HashMap<>();
        Map<Integer,Integer> counts = new HashMap<>();
        int maxCount = 0;
        for (int i = 0;i < nums.length;i ++){//找到数组的度
            if (! counts.containsKey(nums[i])){
                counts.put(nums[i],0);
                starts.put(nums[i],i);
            }
            counts.put(nums[i],counts.get(nums[i]) + 1);
            ends.put(nums[i],i);
            maxCount = Math.max(maxCount, counts.get(nums[i]));
        }
        int minLen = Integer.MAX_VALUE;
        for (Integer key : counts.keySet()){
            if (counts.get(key) == maxCount){
                minLen = Math.min(minLen,ends.get(key) - starts.get(key) + 1);
            }
        }
        return minLen;
    }
}input

② 对元素出现的次数进行桶排序,找到最大值,即位度。而后找到全部出现次数为度大小的数,以后遍历其在数组中的位置,查找最小长度。。。

class Solution { //19ms     public int findShortestSubArray(int[] nums) {         if (nums == null || nums.length == 0) return 0;         int maxNum = 0;         for (int n : nums){             maxNum = Math.max(maxNum,n);//找到数组中的最大元素         }         int[] counts = new int[maxNum + 1];//保证nums中的元素均可以在count中做为索引,从而找出出现次数最多的元素         for(int i = 0 ; i < counts.length; i ++){             counts[i] = 0;         }         for(int i = 0; i < nums.length; i++){//能够获得每一个元素分别出现了多少次             counts[nums[i]] ++;                       }         maxNum = 0;         for(int i = 0; i < counts.length; i++){             if(counts[i] > maxNum)  maxNum = counts[i];//找出数组中出现同一个元素最多的次数         }         if(maxNum == 1)  return 1;         LinkedList<Integer> list = new LinkedList<>();         for(int i = 0; i < counts.length; i++){             if(counts[i] == maxNum){                 list.add(i);             }         }         int minLen = Integer.MAX_VALUE;         for(int num : list){             int left = 0;             int right = nums.length - 1;             while(nums[left] != num) left ++;             while(nums[right] != num) right --;             minLen = Math.min(minLen, right - left + 1);         }         return minLen;     } }

相关文章
相关标签/搜索