class Solution:
def findShortestSubArray(self, nums):
from collections import defaultdict
left, right, count = {}, {}, defaultdict(int)
for i, x in enumerate(nums):
if x not in left:
left[x] = i
right[x] = i
count[x] += 1
degree = max(count.values())
min_length = len(nums)
for x in count:
if count[x] == degree:
min_length = min(min_length, right[x] - left[x] + 1)
return min_length
class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
unordered_map<int, int> left, right, count;
for (int i = 0; i < nums.size(); ++i) {
int x = nums[i];
if (!left.count(x)) left[x] = i;
right[x] = i;
count[x]++;
}
int degree = 0;
for (auto &kv : count) degree = max(degree, kv.second);
int minLength = nums.size();
for (auto &kv : count) {
if (kv.second == degree) {
minLength = min(minLength, right[kv.first] - left[kv.first] + 1);
}
}
return minLength;
}
};
class Solution {
public int findShortestSubArray(int[] nums) {
Map<Integer, Integer> left = new HashMap<>();
Map<Integer, Integer> right = new HashMap<>();
Map<Integer, Integer> count = new HashMap<>();
for (int i = 0; i < nums.length; ++i) {
int x = nums[i];
if (!left.containsKey(x)) left.put(x, i);
right.put(x, i);
count.put(x, count.getOrDefault(x, 0) + 1);
}
int degree = Collections.max(count.values());
int minLength = nums.length;
for (int x : count.keySet()) {
if (count.get(x) == degree) {
minLength = Math.min(minLength, right.get(x) - left.get(x) + 1);
}
}
return minLength;
}
}
var findShortestSubArray = function(nums) {
let left = {}, right = {}, count = {};
for (let i = 0; i < nums.length; ++i) {
let x = nums[i];
if (left[x] === undefined) left[x] = i;
right[x] = i;
count[x] = (count[x] || 0) + 1;
}
let degree = Math.max(...Object.values(count));
let minLength = nums.length;
for (let x in count) {
if (count[x] === degree) {
minLength = Math.min(minLength, right[x] - left[x] + 1);
}
}
return minLength;
};
Given a non-empty array of non-negative integers called 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
itself.
nums
of length 1 or more.nums
.To solve this problem, first, we need to understand what the "degree" of the array means. It is the highest number of times any single element occurs in the array. The challenge is to find the shortest possible contiguous subarray (i.e., a sequence of elements in order, without skipping any) that also has this same degree.
A brute-force approach would be to check every possible subarray and compute its degree, but this would be very slow for large arrays. Instead, we can focus on the elements that contribute to the degree and try to find the smallest window that contains all their occurrences.
This leads to a key insight: for each element that occurs as many times as the degree, the shortest subarray covering all its occurrences is the subarray from its first appearance to its last appearance. We just need to find the minimum length among these.
Here is a step-by-step guide to the optimized algorithm:
We use hash maps (dictionaries) because they allow us to store and retrieve counts and positions in constant time, making the algorithm efficient.
Let's walk through a sample input:
nums = [1, 2, 2, 3, 1, 4, 2]
Thus, the shortest subarray with the same degree as the whole array is of length 6.
nums
.
The key to this problem is recognizing that the shortest subarray with the same degree as the input array must cover all occurrences of at least one element that occurs as often as the degree. By recording the first and last positions of each element and their counts in a single pass, we can efficiently compute the answer in linear time. This approach is both elegant and practical, avoiding unnecessary brute-force checks and leveraging hash maps for fast lookups.