We can create a map of number and frequency. Sort the map based on frequency and return first k elements. But the time complexity will be O(n log n). But of course we can do better.
classSolution {
public List<Integer>topKFrequent(int[] nums, int k) {
Map<Integer, Integer> freq =new HashMap<>(); // Frequency countfor (int num : nums) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
// Using a priority queue (min-heap) PriorityQueue<int[]> heap =new PriorityQueue<>((a, b) -> a[0]- b[0]);
for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
heap.add(newint[]{entry.getValue(), entry.getKey()});
if (heap.size() > k) heap.poll();
}
List<Integer> ans =new ArrayList<>();
for (int[] pair : heap) ans.add(pair[1]);
return ans;
}
}
1
2
3
4
5
6
7
8
classSolution:
deftopKFrequent(self, nums: List[int], k: int) -> List[int]:
freq = Counter(nums) # Frequency count# Using a min-heap to keep the k most frequent elements heap = [(count, num) for num, count in freq.items()]
heapq.heapify(heap)
ans = heapq.nlargest(k, heap)
return [num for _, num in ans]
We can use array of linked list, where we can bucketize the numbers based on there frequency. The bucket index will be frequency, values will be number added to that bucket.
Number of buckets will be = nums.length+1. Why? Because what if all the element occur once, then it is nums.length; Also, 0 for 0 frequency case. This helps in avoiding edge cases, where we need to sometimes do index-1 etc.
publicint[]topKFrequent(int[] nums, int k) {
List<Integer>[] bucket =new List[nums.length+ 1];
Map<Integer, Integer> frequencyMap =new HashMap<>();
for (int num : nums) {
frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
}
for (int key : frequencyMap.keySet()) {
int frequency = frequencyMap.get(key);
if (bucket[frequency]==null) {
bucket[frequency]=new ArrayList<>();
}
bucket[frequency].add(key);
}
int[] ans =newint[k];
int j = 0;
for (int pos = bucket.length- 1; pos >= 0; pos--) {
if(bucket[pos]==null) {
continue;
}
List<Integer> currBucket = bucket[pos];
for(int i =0; i< currBucket.size() && j < k; i++){
ans[j++]= currBucket.get(i);
}
}
return ans;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution:
deftopKFrequent(self, nums: List[int], k: int) -> List[int]:
# Frequency count using Counter freq = Counter(nums)
# Bucket where index represents frequency bucket: List[List[int]] = [[] for _ in range(len(nums) +1)]
# Fill the bucketfor num, count in freq.items():
bucket[count].append(num)
# Extract the top k frequent elements ans = []
for i in range(len(bucket) -1, 0, -1): # Traverse bucket from high to low frequencyif bucket[i]:
ans.extend(bucket[i]) # Add all elements in the current bucketif len(ans) >= k: # Stop when we have enough elementsreturn ans[:k]
return ans