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.
Your task is to find the smallest possible length of a (contiguous) subarray of nums
, that has the same degree as nums
.
Example 1:
Input: nums = [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:
Input: nums = [1,2,2,3,1,4,2] Output: 6 Explanation: The degree is 3 because the element 2 is repeated 3 times. So [2,2,3,1,4,2] is the shortest subarray, therefore returning 6.
Constraints:
nums.length
will be between 1 and 50,000.nums[i]
will be an integer between 0 and 49,999.
class Solution:
def findShortestSubArray(self, nums: List[int]) -> int:
mapper = {}
for i, v in enumerate(nums):
if v in mapper:
arr = mapper[v]
arr[0] += 1
arr[2] = i
else:
arr = [1, i, i]
mapper[v] = arr
max_degree = min_len = 0
for arr in mapper.values():
if max_degree < arr[0]:
max_degree = arr[0]
min_len = arr[2] - arr[1] + 1
elif max_degree == arr[0]:
min_len = min(min_len, arr[2] - arr[1] + 1)
return min_len
class Solution {
public int findShortestSubArray(int[] nums) {
Map<Integer, int[]> mapper = new HashMap<>();
for (int i = 0, n = nums.length; i < n; ++i) {
if (mapper.containsKey(nums[i])) {
int[] arr = mapper.get(nums[i]);
++arr[0];
arr[2] = i;
} else {
int[] arr = new int[]{1, i, i};
mapper.put(nums[i], arr);
}
}
int maxDegree = 0, minLen = 0;
for (Map.Entry<Integer, int[]> entry : mapper.entrySet()) {
int[] arr = entry.getValue();
if (maxDegree < arr[0]) {
maxDegree = arr[0];
minLen = arr[2] - arr[1] + 1;
} else if (maxDegree == arr[0]) {
minLen = Math.min(minLen, arr[2] - arr[1] + 1);
}
}
return minLen;
}
}