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 |
---|---|
Empty input array | Return an empty list as there are no elements to process. |
k is zero | Return an empty list as we need to return the top 0 elements. |
k is larger than the number of unique elements in the input array | Return all unique elements in the array as the top k elements. |
Input array contains only one element | Return the single element in a list if k >= 1, or an empty list if k is zero. |
All elements in the input array are the same | Return the element in a list if k >= 1, or an empty list if k is zero. |
Input array contains negative numbers, zeros, and positive numbers | Frequency counting methods handle all integer values without issue. |
Large input array with a small k, making priority queue inefficient | Bucket sort can be more efficient in this case, providing O(n) time complexity. |
Duplicate frequencies exist: multiple elements have the same frequency and could qualify for the top k | The algorithm should return any k elements that satisfy the frequency requirement, as the problem states that the order doesn't matter. |