Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order.
Use a hash map to count frequencies, then use a min-heap to track top k elements.
More efficient approach using bucket sort concept.
nums = [1,1,1,2,2,3], k = 2
Frequency map:
1: 3, 2: 2, 3: 1
Buckets (index = frequency):
[0]: []
[1]: [3]
[2]: [2]
[3]: [1]
Collect from end: [1, 2] (top 2 most frequent)
1/**
2 * Top K Frequent Elements
3 * Time: O(n) with bucket sort, O(n log k) with heap
4 * Space: O(n)
5 */
6
7import java.util.*;
8
9// Approach 1: Bucket Sort (Optimal)
10class Solution {
11 public int[] topKFrequent(int[] nums, int k) {
12 // Count frequencies
13 Map<Integer, Integer> count = new HashMap<>();
14 for (int num : nums) {
15 count.put(num, count.getOrDefault(num, 0) + 1);
16 }
17
18 // Create buckets
19 List<Integer>[] buckets = new List[nums.length + 1];
20 for (int i = 0; i < buckets.length; i++) {
21 buckets[i] = new ArrayList<>();
22 }
23
24 for (int num : count.keySet()) {
25 int freq = count.get(num);
26 buckets[freq].add(num);
27 }
28
29 // Collect k most frequent
30 int[] result = new int[k];
31 int idx = 0;
32 for (int i = buckets.length - 1; i >= 0 && idx < k; i--) {
33 for (int num : buckets[i]) {
34 result[idx++] = num;
35 if (idx == k) return result;
36 }
37 }
38
39 return result;
40 }
41}
42
43// Approach 2: Heap
44class Solution2 {
45 public int[] topKFrequent(int[] nums, int k) {
46 Map<Integer, Integer> count = new HashMap<>();
47 for (int num : nums) {
48 count.put(num, count.getOrDefault(num, 0) + 1);
49 }
50
51 PriorityQueue<Integer> heap = new PriorityQueue<>(
52 (a, b) -> count.get(a) - count.get(b)
53 );
54
55 for (int num : count.keySet()) {
56 heap.offer(num);
57 if (heap.size() > k) {
58 heap.poll();
59 }
60 }
61
62 int[] result = new int[k];
63 for (int i = 0; i < k; i++) {
64 result[i] = heap.poll();
65 }
66
67 return result;
68 }
69}
70