Given an integer array nums
and an integer k
, return the k
most frequent elements. You may return the answer in any order.
For example:
nums = [1,1,1,2,2,3], k = 2
should return [1, 2]
(or [2, 1]
).nums = [1], k = 1
should return [1]
.Here are some constraints to consider:
1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
k
is in the range [1, the number of unique elements in the array]
.Can you write a function to solve this problem efficiently? What is the time and space complexity of your solution? Consider edge cases such as an empty input array or when k
is equal to the number of unique elements. Finally, consider the follow-up question: Can you design an algorithm with a time complexity better than O(n log n), where n is the array's size?
A brute force approach involves counting the frequency of each element in the array and then sorting the elements based on their frequencies. Finally, we pick the top k
elements.
nums
and use a hash map (dictionary) to store the frequency of each element.k
elements from the sorted list.Big O Analysis:
nums
. This is primarily due to the sorting step.from collections import Counter
def top_k_frequent_brute_force(nums, k):
# Count frequencies using Counter
counts = Counter(nums)
# Sort by frequency
sorted_counts = sorted(counts.items(), key=lambda item: item[1], reverse=True)
# Get the top k elements
top_k = [item[0] for item in sorted_counts[:k]]
return top_k
A more efficient solution uses a min-heap to keep track of the k
most frequent elements. This avoids sorting all elements and provides a better time complexity.
k
. Iterate through the hash map. If the current element's frequency is greater than the smallest frequency in the heap, remove the smallest element and add the current element.k
frequent elements.Big O Analysis:
nums
. Building the frequency map takes O(n) time, and each heap operation takes O(log k) time. In the worst case, we might iterate through all n elements.k
elements, so it can also be seen as O(k)).import heapq
from collections import Counter
def top_k_frequent_heap(nums, k):
# Count frequencies using Counter
counts = Counter(nums)
# Create a min-heap
heap = []
for num, freq in counts.items():
heapq.heappush(heap, (freq, num))
if len(heap) > k:
heapq.heappop(heap)
# Extract the top k elements from the heap
top_k = [num for freq, num in heap]
top_k.reverse()
return top_k
k
is 0, return an empty list.nums = [1,1,1,1], k = 1
. The result should be [1]
def top_k_frequent(nums, k):
if not nums or k <= 0:
return []
return top_k_frequent_heap(nums, k)