Leetcode697. 數組的度(數組, 下標)

鏈接:https://leetcode-cn.com/problems/degree-of-an-array
給定一個非空且只包含非負數的整數數組 nums, 數組的度的定義是指數組裏任一元素出現頻數的最大值。
你的任務是找到與 nums 擁有相同大小的度的最短連續子數組,返回其長度。

示例 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.

示例 2:

輸入: [1,2,2,3,1,4,2]
輸出: 6

注意:
nums.length 在1到50,000區間範圍內。
nums[i] 是一個在0到49,999範圍內的整數。

/* 思路
找出最大的度, 和最大的數

創建一個長度爲最大數的數組(> 原數組長度)
原數組的值作爲新創建數組的下標,計算出現次數爲度數的數
>> 改進,同時記錄第一次出現的位置,和最後一次出現的位置。

計算出現次數爲度數的數的最小間隔即可(包含所有出現的次數), 求出最小長度(記錄)
*/

int findShortestSubArray(int* nums, int numsSize){
    // 找最大的數, new_nums開空間用
    int max_num = -1;
    int i = 0;
    for(i = 0; i < numsSize; i++){
        max_num = nums[i] > max_num ? nums[i] : max_num;
    }

    // 記錄每個數出現的次數, 首次出現的位置 + 最後出現的位置
    int nnSize = max_num > numsSize ? max_num : numsSize;
    int **new_nums = (int **)calloc(1, ++nnSize * sizeof(int *)); // [2,2] , nnSize 需要擴展一位
    for(i = 0; i < nnSize; i++){
        new_nums[i] = (int *)calloc(1, sizeof(int) * 3);
    }

    for(i = 0; i < numsSize; i++){
        new_nums[nums[i]][0]++;
        if(1 == new_nums[nums[i]][0]){
            new_nums[nums[i]][1] = i; // 首次出現的位置
        }
        new_nums[nums[i]][2] = i; // 最後出現的位置 // 預設爲1
    }

    // 查找最大的度
    int max_degree = 0;
    for(i = 0; i < numsSize; i++){
        max_degree = new_nums[nums[i]][0] > max_degree ?  new_nums[nums[i]][0] : max_degree;
    }

    // 查找最小的子數組
    int min_num = INT_MAX;
    for(i = 0; i < numsSize; i++){
        if(new_nums[nums[i]][0] == max_degree){
            int size = new_nums[nums[i]][2] - new_nums[nums[i]][1] + 1;
            min_num = min_num > size ? size : min_num;
        }
    }

    // 釋放內存
    for(i = 0; i < nnSize; i++){
        free(new_nums[i]);
    }
    free(new_nums);
    return min_num;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章