Given an integer array nums
and an integer k
, return the k
most frequent elements. You may return the answer in any order.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2]
Example 2:
Input: nums = [1], k = 1 Output: [1]
Constraints:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
k
is in the range [1, the number of unique elements in the array]
.Follow up: Your algorithm's time complexity must be better than O(n log n)
, where n is the array's size.
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 finding the most frequent items involves counting how often each item appears in a list. Then, we simply pick out the items with the highest counts. This is done by comparing each item's count against every other item's count.
Here's how the algorithm would work step-by-step:
def top_k_frequent_elements_brute_force(numbers, k_most_frequent):
item_counts = {}
for number in numbers:
if number in item_counts:
item_counts[number] += 1
else:
item_counts[number] = 1
unique_items = list(item_counts.keys())
top_k_frequent = []
for item_to_check in unique_items:
frequency_count = item_counts[item_to_check]
is_among_top_k = True
# Check if the current item is frequent enough to be in the top k
for other_item in unique_items:
if item_counts[other_item] > frequency_count:
is_among_top_k = False
break
if is_among_top_k:
top_k_frequent.append(item_to_check)
# Limit the result to the top k elements
return top_k_frequent[:k_most_frequent]
To find the most frequent elements efficiently, we use a clever method to count how often each element appears and then quickly identify the top ones. We organize elements based on their frequency, allowing us to grab the most frequent ones quickly.
Here's how the algorithm would work step-by-step:
def top_k_frequent(numbers, k_most_frequent):
element_frequency = {}
for number in numbers:
element_frequency[number] = element_frequency.get(number, 0) + 1
# Create buckets to store elements based on frequency.
frequency_buckets = [[] for _ in range(len(numbers) + 1)]
for number, frequency in element_frequency.items():
frequency_buckets[frequency].append(number)
result = []
# Iterate from highest frequency to lowest.
for frequency in range(len(numbers), 0, -1):
if frequency_buckets[frequency]:
# Add elements to result until we have k elements.
for number in frequency_buckets[frequency]:
result.append(number)
if len(result) == k_most_frequent:
return result
return result
Case | How to Handle |
---|---|
Input array is empty or null | The solution should handle this gracefully by returning an empty list, as there are no elements to count. |
The value of k is equal to the number of unique elements in the array | The solution should return all the unique elements, as they are all part of the top k most frequent. |
The value of k is 1 | The algorithm correctly identifies and returns the single most frequent element in the array. |
All elements in the array are identical | The frequency map will contain only one entry, and the solution will correctly return that single element. |
All elements in the array are unique | The solution must return any k elements from the input array, since all elements have a frequency of one. |
Multiple elements have the same frequency, creating a tie for the kth spot | The algorithm can return any of the tied elements to complete the set of k, as the problem allows any valid answer. |
The input array contains negative numbers and zeros | A hash map correctly handles any integer value as a key, so negative numbers and zeros are processed just like positive ones. |
The input array is very large, potentially causing memory issues | A streaming or partial processing approach might be needed if the frequency map becomes too large to fit in memory. |