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.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for the Degree of an Array problem involves checking every possible sub-section of the data. We identify the most frequent value, and then look at every possible sub-section to find the shortest one that contains all occurrences of that value.
Here's how the algorithm would work step-by-step:
def degree_of_an_array_brute_force(numbers):
most_frequent_value = 0
max_frequency = 0
frequency_map = {}
for number in numbers:
if number not in frequency_map:
frequency_map[number] = 0
frequency_map[number] += 1
if frequency_map[number] > max_frequency:
max_frequency = frequency_map[number]
most_frequent_value = number
shortest_sub_array_length = len(numbers)
# Iterate through all possible sub arrays to find the shortest one containing the most frequent element
for sub_array_start_index in range(len(numbers)):
for sub_array_end_index in range(sub_array_start_index, len(numbers)):
sub_array = numbers[sub_array_start_index:sub_array_end_index + 1]
sub_array_frequency_map = {}
for number in sub_array:
if number not in sub_array_frequency_map:
sub_array_frequency_map[number] = 0
sub_array_frequency_map[number] += 1
# Check if the sub array contains all instances of the most frequent value
if most_frequent_value in sub_array_frequency_map and sub_array_frequency_map[most_frequent_value] == frequency_map[most_frequent_value]:
#Keep track of the smallest length so far
shortest_sub_array_length = min(shortest_sub_array_length, len(sub_array))
return shortest_sub_array_length
To find the 'degree' of an array (the most frequent number) and the smallest part of the array that contains all instances of that number, we use a clever tracking system. We remember the first and last seen position of each number, and how many times each number appears. This lets us quickly check only the shortest parts that contain the most common number.
Here's how the algorithm would work step-by-step:
def find_shortest_subarray(nums):
first_seen = {}
last_seen = {}
frequency_count = {}
for index, number in enumerate(nums):
if number not in first_seen:
first_seen[number] = index
last_seen[number] = index
frequency_count[number] = frequency_count.get(number, 0) + 1
degree = 0
for number in frequency_count:
degree = max(degree, frequency_count[number])
most_frequent_numbers = [
number for number, count in frequency_count.items() if count == degree
]
minimum_length = float('inf')
# We need to only check the most frequent numbers.
for number in most_frequent_numbers:
first_index = first_seen[number]
last_index = last_seen[number]
# Calculate the length of the subarray containing all occurrences
current_length = last_index - first_index + 1
# Update the minimum length if the current length is smaller
minimum_length = min(minimum_length, current_length)
return minimum_length
Case | How to Handle |
---|---|
Empty or null input array | Return 0 if the input array is empty or null as there is no subarray with any degree. |
Array with a single element | Return 1 as the array itself is the shortest subarray with degree 1. |
Array with all elements having the same value | Return 1 as any single element constitutes the shortest subarray with the maximum degree. |
Array with elements having a skewed distribution (one element dominates) | The solution should correctly identify the degree and find the shortest subarray containing that dominant element. |
Array with multiple elements sharing the same maximum frequency (same degree) | The solution should iterate and check the shortest subarray for each element with the maximum frequency and return the minimum length amongst them. |
Large input array with large integer values | The solution's space complexity using hash maps should be considered for very large arrays, and avoid potential Integer overflow during length calculations. |
Array containing only zeros | The solution handles this like any other array where a value appears multiple times, determining the degree and shortest subarray length correctly. |
Integer overflow potential when calculating lengths/indices | Use long to store length and index differences to prevent potential overflow issues, especially with very large arrays. |