Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order.
1 <= nums.length <= 105-104 <= nums[i] <= 104k is in the range [1, the number of unique elements in the array].Your algorithm's time complexity must be better than $O(n \log n)$, where n is the array's size.
We iterate through the nums array once to build the frequency map, which takes time. Sorting the frequency map takes time, where m is the number of unique elements in the array. In the worst case, m can be equal to n (when all elements are unique), leading to time complexity.
We use a hash map to store the frequency of each element, which requires space in the worst case.
In this solution, we first create a frequency map to count the occurrences of each number in the nums array. We then sort this frequency map based on the frequency values in descending order. Finally, we return the keys of the sorted map, which represent the numbers, and slice the first k elements to get the top k frequent elements.
We iterate through the nums array once to build the frequency map, which takes time. We then iterate through the frequency map, which takes time, where m is the number of unique elements. For each element, we perform a heap operation that takes time. In the worst case, m can be equal to n (when all elements are unique), leading to time complexity.
We use a min-heap to store the top k frequent elements, which requires space. Additionally, we use a hash map to store the frequency of each element, which requires space, where m is the number of unique elements. In the worst case, m can be equal to n, leading to space complexity. However, since we only keep track of the top k elements, the overall space complexity is .
In this solution, we use a min-heap (priority queue) to keep track of the top k frequent elements. We first build a frequency map to count the occurrences of each number. Then, we iterate through the frequency map and push each number along with its frequency into the min-heap. If the size of the heap exceeds k, we remove the smallest element (the one with the lowest frequency). Finally, we extract the numbers from the heap, which represent the top k frequent elements.
We iterate through the nums array once to build the frequency map, which takes time. We then iterate through the frequency map to fill the buckets, which takes time, where m is the number of unique elements. Finally, we iterate through the buckets to collect the top k elements, which takes time in the worst case (when all elements are unique). Therefore, the overall time complexity is .
We use a frequency map to store the count of each number, which takes space, where m is the number of unique elements. We also use a list of buckets to group numbers by their frequency, which takes space in the worst case. Therefore, the overall space complexity is .
In this solution, we use a bucket sort approach to group numbers based on their frequency. We first build a frequency map to count the occurrences of each number. Then, we create a list of buckets where the index represents the frequency and the value is a list of numbers that have that frequency. Finally, we iterate through the buckets in reverse order (from highest frequency to lowest) and add numbers to the result list until we have k elements.
| Approach | Rating | Time Complexity | Space Complexity | Advantages | Disadvantages |
|---|---|---|---|---|---|
| Sorting | Simple to understand and implement | ⚠️ Does not meet the follow-up requirement of better than | |||
| Min-Heap | Efficient when k is much smaller than n, meets follow-up requirement | Requires understanding of heap data structure | |||
| Bucket Sort | Linear time complexity, no sorting or heap overhead, meets follow-up requirement | Requires extra space for the bucket array |
The optimal approach for this problem is Solution 3: Bucket Sort, which achieves time complexity and space complexity. This approach leverages the fact that element frequencies are bounded by the array length, using bucket indices to represent frequencies and avoiding any sorting or heap operations entirely.
class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: my_dict = defaultdict(int)
# Create a list to store the frequency of each number: frequency[num] = count for num in nums: my_dict[num] += 1
# Sort the dictionary by frequency in descending order sorted_dict = dict(sorted(my_dict.items(), key=lambda x: x[1], reverse=True))
return list(sorted_dict.keys())[:k]