Top K Frequent Elements Using Heap in DSA C# - Time & Space Complexity
We want to understand how the time needed to find the top K frequent elements changes as the input grows.
How does the program's speed change when the list of numbers gets bigger?
Analyze the time complexity of the following code snippet.
var frequency = new Dictionary<int, int>();
foreach (var num in nums) {
frequency[num] = frequency.TryGetValue(num, out int cnt) ? cnt + 1 : 1;
}
var heap = new PriorityQueue<int, int>();
foreach (var kvp in frequency) {
heap.Enqueue(kvp.Key, -kvp.Value);
if (heap.Count > k) heap.Dequeue();
}
var result = new List<int>();
while (heap.Count > 0) result.Add(heap.Dequeue());
return result;
This code counts how often each number appears, then uses a heap to keep track of the top K frequent numbers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through the input array to count frequencies and looping through the frequency dictionary to manage the heap.
- How many times: The first loop runs once for each element in the input (n times). The second loop runs once for each unique number (m times).
As the input size grows, counting frequencies grows linearly with n. Managing the heap grows with m and k.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 to count + heap operations on unique elements |
| 100 | About 100 to count + heap operations on unique elements |
| 1000 | About 1000 to count + heap operations on unique elements |
Pattern observation: Counting grows directly with input size, heap operations grow with unique elements and k, usually smaller than n.
Time Complexity: O(n + m log k)
This means the time grows mostly with the input size n, but the heap operations depend on k, making it efficient when k is small.
[X] Wrong: "The heap operations take O(n log n) because the heap size grows with n."
[OK] Correct: The heap size is kept at most k, so heap operations take O(log k), not O(log n), which is much faster when k is small.
Understanding how to use heaps to efficiently find top K elements is a valuable skill that shows you can handle large data smartly and quickly.
"What if we used a simple sort on all unique elements instead of a heap? How would the time complexity change?"
Practice
Top K Frequent Elements problem?Solution
Step 1: Understand the role of a heap
A heap is a special tree-based data structure that helps efficiently find and maintain the largest or smallest elements.Step 2: Apply heap to the problem context
In the Top K Frequent Elements problem, a heap helps keep track of the K elements with the highest frequency without sorting the entire list.Final Answer:
To efficiently keep track of the top K elements by frequency -> Option CQuick Check:
Heap = Efficient top K tracking [OK]
- Thinking heap sorts all elements fully
- Confusing heap with simple list or array
- Ignoring frequency importance
SortedSet for integers?Solution
Step 1: Identify data structure for min-heap
A min-heap can be implemented using aSortedSetin C# because it keeps elements sorted automatically.Step 2: Check code correctness
var minHeap = new SortedSet<int>(); declares aSortedSet<int>, which acts like a min-heap by keeping smallest element accessible.Final Answer:
var minHeap = new SortedSet<int>(); -> Option DQuick Check:
SortedSet = min-heap structure [OK]
- Using List instead of a heap structure
- Confusing Dictionary with heap
- Using Stack which is LIFO, not heap
int[] nums = {1,1,1,2,2,3};
int k = 2;
var freq = new Dictionary();
foreach(var num in nums) freq[num] = freq.GetValueOrDefault(num, 0) + 1;
var heap = new SortedSet<(int freq, int num)>();
foreach(var pair in freq) {
heap.Add((pair.Value, pair.Key));
if(heap.Count > k) heap.Remove(heap.Min);
}
var result = heap.Select(x => x.num).ToList();
Console.WriteLine(string.Join(", ", result));Solution
Step 1: Count frequencies
Frequencies are: 1 -> 3 times, 2 -> 2 times, 3 -> 1 time.Step 2: Use min-heap to keep top 2 frequent
Heap keeps pairs (freq, num). It adds all pairs: (3,1), (2,2), (1,3). When size > 2, removes smallest freq (1,3). Leaving (2,2) and (3,1). SortedSet iterates in ascending order: (2,2), then (3,1).Step 3: Output order
Result list is created by selecting num from heap in ascending order of freq, so output is "2, 1".Final Answer:
2, 1 -> Option AQuick Check:
Top 2 frequent = 2, 1 [OK]
- Not removing smallest freq when heap size exceeds k
- Mixing element and frequency order
- Printing frequencies instead of elements
int[] nums = {4,4,4,6,6,7};
int k = 1;
var freq = new Dictionary();
foreach(var num in nums) freq[num] = freq.GetValueOrDefault(num, 0) + 1;
var heap = new SortedSet<(int freq, int num)>();
foreach(var pair in freq) {
heap.Add((pair.Value, pair.Key));
if(heap.Count > k) heap.Remove(heap.Max);
}
var result = heap.Select(x => x.num).ToList();
Console.WriteLine(string.Join(", ", result));Solution
Step 1: Understand heap removal logic
Heap is a min-heap by frequency, so smallest freq is at Min, largest at Max.Step 2: Identify incorrect removal
Code removes heap.Max when size exceeds k, which removes the largest frequency element instead of smallest, causing wrong result.Final Answer:
Removing heap.Max instead of heap.Min causes wrong elements removal -> Option AQuick Check:
Remove heap.Min to keep top frequent [OK]
- Removing heap.Max instead of heap.Min
- Confusing frequency and element order
- Not updating frequency dictionary correctly
nums = {5,3,1,1,1,3,73,1} and k = 2, which approach correctly returns the top 2 frequent elements using a heap in C#?
A) Use a max-heap to store all elements and pop k times.
B) Use a min-heap of size k to keep top frequent elements by frequency.
C) Sort the array and pick last k elements.
D) Use a queue to store elements and count frequencies later.Solution
Step 1: Understand frequency counting
Count frequencies: 1 -> 4 times, 3 -> 2 times, 5 -> 1 time, 73 -> 1 time.Step 2: Use min-heap of size k
Use a min-heap to keep only top k frequent elements by frequency. When heap size exceeds k, remove smallest frequency element.Step 3: Why other options fail
A) Max-heap of all elements is inefficient. C) Sorting array doesn't group frequencies. D) Queue doesn't help frequency counting efficiently.Final Answer:
Use a min-heap of size k to keep top frequent elements by frequency. -> Option BQuick Check:
Min-heap size k = correct approach [OK]
- Using max-heap for all elements wastes memory
- Sorting array ignores frequency counts
- Using queue without frequency map
Ready to prove it?
Pass the test and this pattern moves unknown
