Problem Overview
You are given an array nums and an integer k.
Your task is to return the k elements that appear the most often in the array.
Example input:
nums = [1,2,1,2,1,2,3,1,3,2]
k = 2
Frequencies:
-
1 appears 4 times
-
2 appears 4 times
-
3 appears 2 times
The two most frequent elements are:
[1, 2]
Approach 1: Using Sorting (O(n log n))
Steps:
-
Build a frequency map (number → count).
-
Put all pairs
(number, count)into a vector. -
Sort the vector by count in descending order.
-
Take the first
kelements.
Why O(n log n)?
Because the sorting step requires log time as the number of unique elements increases.
This method is simple but not optimal for very large input sizes.
Approach 2: Bucket Counting (O(n))
This method avoids sorting completely.
Steps:
-
Build a frequency map.
-
Create a structure where index = frequency.
Example:bucket[4] = {1, 2}because both appear 4 times. -
Start from the highest frequency and collect numbers.
-
Stop when you collect
kelements.
Why O(n)?
Counting + bucket creation + scanning are all linear operations.
This approach satisfies the follow-up requirement:
Must be better than O(n log n).
Final Code (O(n) Bucket Approach)
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> freq;
for (int x : nums) freq[x]++;
vector<vector<int>> bucket(nums.size() + 1);
for (auto &p : freq) bucket[p.second].push_back(p.first);
vector<int> result;
for (int i = bucket.size() - 1; i >= 0 && result.size() < k; i--) {
for (int num : bucket[i]) {
result.push_back(num);
if (result.size() == k) break;
}
}
return result;
}
};
