1. 程式人生 > >【兩次過】Lintcode 1078. 陣列的度

【兩次過】Lintcode 1078. 陣列的度

給定由非負整陣列成的非空陣列,陣列的度定義為出現頻率最高的元素。

找出最短的連續子陣列,並使得它和原陣列有相同的度。返回該連續子陣列的長度。

樣例

輸入: [1, 2, 2, 3, 1] 輸出: 2 解釋: 輸入陣列的度是2,1和2都出現了兩次。 具有相同度的子串包括: [1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2] 其中長度最短為2。所以返回2。

注意事項

nums.length的範圍在1到50,000之間。nums[i]是範圍為0到49,999的整數。

解題思路:

用map儲存每種元素出現的次數,得到最大度數。再找到最大度數元素的首位元素下標,即計算出當前最大度連續子陣列的最小長度,最後選最小的長度即可。

public class Solution {
    /**
     * @param nums: a list of integers
     * @return: return a integer
     */
    public int findShortestSubArray(int[] nums) {
        // write your code here
        Map<Integer,Integer> map = new HashMap<>(); //key為陣列中的數字,value為每種數字的度數
        int maxDo = 0;//最大度的次數
        int res = Integer.MAX_VALUE;//最短的連續子陣列的長度
        
        for(int num : nums){
            if(map.get(num) == null)
                map.put(num,1);
            else
                map.put(num,map.get(num)+1);
                
            if(map.get(num) >= maxDo)
                maxDo = map.get(num);
        }
            
        for(Integer key : map.keySet()){
            if(map.get(key) != maxDo)
                continue;
            
            int firstIndex = 0;
            int lastIndex = 0;
            //定位當前最大度元素的首元素下標
            for(int i=0 ; i<nums.length ; i++){
                if(nums[i] == key){
                    firstIndex = i;
                    lastIndex = i;
                    break;
                }
            }
            
            //定位當前最大度元素的尾元素下標
            if(maxDo > 1){
                for(int i=nums.length-1 ; i>=0 ; i--){
                    if(nums[i] == key){
                        lastIndex = i;
                        break;
                    }
                }
            }
            
            int temp = lastIndex - firstIndex + 1; //當前最大度連續子陣列的長度
            if(temp < res)
                res = temp;
        }
            
        return res;
    }
}