Kth Smallest Element Using Min Heap in DSA C - Time & Space Complexity
We want to understand how the time needed to find the kth smallest element using a min heap changes as the input size grows.
Specifically, how does the number of operations increase when the array size or k changes?
Analyze the time complexity of the following code snippet.
#include <stdio.h>
#include <stdlib.h>
void heapify(int arr[], int n, int i) {
int smallest = i;
int left = 2*i + 1;
int right = 2*i + 2;
if (left < n && arr[left] < arr[smallest]) smallest = left;
if (right < n && arr[right] < arr[smallest]) smallest = right;
if (smallest != i) {
int temp = arr[i]; arr[i] = arr[smallest]; arr[smallest] = temp;
heapify(arr, n, smallest);
}
}
int extractMin(int arr[], int *n) {
int root = arr[0];
arr[0] = arr[*n - 1];
(*n)--;
heapify(arr, *n, 0);
return root;
}
int kthSmallest(int arr[], int n, int k) {
// Build min heap
for (int i = n/2 - 1; i >= 0; i--) heapify(arr, n, i);
// Extract min k-1 times
for (int i = 0; i < k - 1; i++) extractMin(arr, &n);
return arr[0];
}
This code builds a min heap from an array and extracts the minimum element k-1 times to find the kth smallest element.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Heapify calls during building the heap and after each extraction.
- How many times: Heapify is called once for each non-leaf node during build (about n/2 times), and then k-1 times after each extraction.
Building the heap takes time proportional to the number of elements, and each extraction involves heapify which depends on the heap height.
| Input Size (n) | Approx. Operations |
|---|---|
| 10, k=3 | Build heap ~ 20 ops, Extract 2 times ~ 6 ops each |
| 100, k=10 | Build heap ~ 200 ops, Extract 9 times ~ 60 ops each |
| 1000, k=100 | Build heap ~ 2000 ops, Extract 99 times ~ 600 ops each |
Pattern observation: Build heap grows roughly linearly with n, extraction grows with k times log n, so total grows with n plus k log n.
Time Complexity: O(n + k log n)
This means the time grows linearly with the array size plus k times the logarithm of the array size.
[X] Wrong: "Extracting the kth smallest element using a min heap always takes O(n log n) time because we do k extractions."
[OK] Correct: Actually, building the heap is O(n), and each extraction is O(log n), so total is O(n + k log n), which can be much faster if k is small.
Understanding this time complexity helps you explain why using a min heap is efficient for finding the kth smallest element, a common problem in interviews.
"What if we used a max heap of size k instead of a min heap of size n? How would the time complexity change?"
Practice
kth smallest element using a min heap?Solution
Step 1: Understand min heap property
A min heap always keeps the smallest element at the root, so extracting the root gives the smallest element.Step 2: Extract minimum
By extracting the rootktimesktimes, we get thekthsmallest element at the last extraction.Final Answer:
Build a min heap and extract minimumktimes -> Option CQuick Check:
Min heap root extraction = kth smallest element [OK]
- Using max heap instead of min heap
- Sorting array instead of using heap
- Extracting min less or more than k times
Solution
Step 1: Identify min heap syntax in C++ STL
To create a min heap, usepriority_queuewithgreater<int>comparator.Step 2: Check options
priority_queue<int, vector<int>, greater<int>>usesgreater<int>which creates a min heap.priority_queue<int>directly, the option withless<int>, andmake_heapwith default comparator all create max heaps.Final Answer:
Use priority_queue with greater comparator -> Option DQuick Check:
Min heap = priority_queue with greater comparator [OK]
- Using default priority_queue which is max heap
- Confusing less and greater comparators
- Using make_heap without comparator
int arr[] = {7, 10, 4, 3, 20, 15};
int n = 6, k = 3;
// Build min heap from arr
// Extract min k times
// Print last extracted element
// Assume min heap functions work correctly
Solution
Step 1: Sort elements mentally or extract min
Sorted array: [3, 4, 7, 10, 15, 20]. Extract min 3 times: 3, 4, 7.Step 2: The 3rd extracted min is the 3rd smallest
The 3rd smallest element is 7.Final Answer:
7 -> Option BQuick Check:
3rd smallest = 7 [OK]
- Picking the 2nd or 4th extracted element
- Confusing kth smallest with kth largest
- Not building min heap correctly
int arr[] = {5, 3, 8, 1, 2};
int k = 2;
// Build min heap from arr
for (int i = 0; i <= k; i++) {
extractMin();
}
print last extracted element;
Solution
Step 1: Analyze loop condition
The loop runs from 0 to k inclusive, so it runs k+1 times, extracting one extra element.Step 2: Correct loop to run exactly k times
Loop should run whilei < kto extract min exactly k times.Final Answer:
Loop runs one extra time; should be i < k -> Option AQuick Check:
Extract min exactly k times = loop i < k [OK]
- Using <= k causing extra extraction
- Not building min heap before extraction
- Confusing extractMin with extractMax
arr = {12, 3, 5, 7, 19}, write the steps to find the 4th smallest element using a min heap and explain why this method is efficient compared to sorting the entire array.Solution
Step 1: Build a min heap from the array
Insert all elements into a min heap so the smallest element is at the root.Step 2: Extract the minimum element 4 times
Each extraction removes the smallest element. The 4th extraction gives the 4th smallest element.Step 3: Efficiency explanation
Building a heap takes O(n), each extraction O(log n), total O(n + k log n) which is efficient for large arrays compared to O(n log n) sorting.Final Answer:
Build min heap, extract min 4 times; efficient because heap operations are O(log n) each -> Option AQuick Check:
Min heap extraction = kth smallest efficiently [OK]
- Using max heap for kth smallest
- Sorting entire array unnecessarily
- Using linear search which is slower
Ready to prove it?
Pass the test and this pattern moves unknown
