鏈接:https://leetcode-cn.com/problems/degree-of-an-array
給定一個非空且只包含非負數的整數數組 nums, 數組的度的定義是指數組裏任一元素出現頻數的最大值。
你的任務是找到與 nums 擁有相同大小的度的最短連續子數組,返回其長度。
示例 1:
輸入: [1, 2, 2, 3, 1]
輸出: 2
解釋:
輸入數組的度是2,因爲元素1和2的出現頻數最大,均爲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;
}