- Link: 347.Top K Frequent Elements - Medium
- Track: NeetCode150
Question
Example 1:
- Input: nums =
[1,1,1,2,2,3], k = 2 - Output:
[1,2]
Restate the problem
- Given an array of
numsand an integerk - Return the
kmost frequency elements - Constraints:
- Assume the answer is unique
Edge Case
nums = [1,1,1],k = 1→ return[1]- Negative numbers, nums =
[-1,-1,0,0,0], k = 1 → return[0] [], k = 2→ return[]
| Method | Approach | Time Complexity | Space Complexity |
|---|---|---|---|
| Method 1 ⭐ | Bucket Sort | ||
| Method 2 ⭐ | Heap | ||
| Method 3 | Counter + Sort |
Method 1 - Bucker Sort
- Why Bucket Sort works?
- Bucket sort works when the
keyin a small integer range.1....n, bounded integer range
- Bucket sort works when the
Approach
- Use Counter to build
{num: freq} - Create
buckets,bucket[freq]stores all numbers with that frequency - Scan bucket from n down to 1
- collect numbers until we have
k
- collect numbers until we have
Complexity
- Time Complexity:
- Scan take , m ≤ n, so O(n+m)=O(n)
- Space Complexity:
Code
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
n = len(nums)
counter = Counter(nums) # {num: freq} O(n)
bucket = [[] for _ in range(n + 1)]
for num, freq in counter.items():
bucket[freq].append(num)
res = []
for idx in range(len(bucket) - 1, -1, -1): # O(n)
for num in bucket[idx]: # O(m)
res.append(num)
if len(res) == k:
return res
return resMethod 2 - Heap
Approach
- Use
Counterto build{num: freq} - Maintain a min-heap of size at most
k - For each num in
Counter:- heap push
- if heap size > k, heappop to remove the smallest frequency
- Return the remaining in the heap
Complexity
- Time Complexity:
- m = the number of unique
num - k = the number of elements need to return
- m = the number of unique
- Space Complexity:
- worst case:
Code
from collections import Counter
import heapq
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
counter = Counter(nums) # O(n)
heap = []
for num, freq in counter.items(): # O(m)
heapq.heappush(heap, (freq, num)) # O(logk)
if len(heap) > k:
heapq.heappop(heap)
return [num for freq, num in heap]Method 2 - Counter + Sort
Complexity
- Time Complexity:
- n = len(
nums) - m = the number of unique
num
- n = len(
- Space Complexity:
Code
from collections import Counter
import heapq
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
counter = Counter(nums) # O(n)
freqs = [(freq, num)for num, freq in counter.items()] # O(m)
freqs.sort(reverse=True) # O(mlogm)
return [num for _, num in freqs[:k]] # O(k)