數組的子數組中度與原數組相同的個數 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;     } }

相關文章
相關標籤/搜索