Kth Largest Element Using Max Heap in DSA Go - Time & Space Complexity
We want to understand how long it takes to find the kth largest number using a max heap.
How does the time needed grow as the list of numbers gets bigger?
Analyze the time complexity of the following code snippet.
func findKthLargest(nums []int, k int) int {
maxHeap := &MaxHeap{}
for _, num := range nums {
maxHeap.Insert(num)
}
var kthLargest int
for i := 0; i < k; i++ {
kthLargest = maxHeap.ExtractMax()
}
return kthLargest
}
This code builds a max heap from the list, then removes the largest element k times to find the kth largest.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Inserting each number into the max heap and extracting the max element.
- How many times: Insert runs once for each of n numbers; ExtractMax runs k times.
As the list size n grows, inserting all numbers takes more time, and extracting k times adds extra work.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 insertions + k extractions |
| 100 | About 100 insertions + k extractions |
| 1000 | About 1000 insertions + k extractions |
Pattern observation: Insertion cost grows roughly with n log n, extraction cost grows with k log n.
Time Complexity: O(n log n + k log n)
This means the time grows mostly by n times log n for building the heap, plus k times log n for removing elements.
[X] Wrong: "Building the heap is just O(n) so total time is O(n + k log n)."
[OK] Correct: While heap construction can be O(n), inserting elements one by one as here costs O(n log n), which dominates the time.
Understanding this time complexity helps you explain your approach clearly and shows you know how data structures affect performance.
"What if we used a min heap of size k instead of a max heap of size n? How would the time complexity change?"
Practice
kth largest element using a max heap?Solution
Step 1: Understand max heap property
A max heap always keeps the largest element at the root, so extracting the root gives the current largest element.Step 2: Extract max
By removing the rootktimesktimes, the last extracted element is thekthlargest.Final Answer:
Build a max heap and extract maxktimes -> Option AQuick Check:
Max heap extraction = kth largest element [OK]
k times to get kth largest [OK]- Using min heap instead of max heap
- Sorting and picking wrong index
- Confusing kth largest with kth smallest
arr using the container/heap package?Solution
Step 1: Understand Go heap package usage
The Go heap package requires a type implementing heap.Interface to define heap behavior (min or max).Step 2: Use a custom maxHeap type
To create a max heap, define a type with Len, Less (inverted for max), Swap, Push, Pop methods, then call heap.Init(&maxHeap).Final Answer:
heap.Init(&maxHeap) where maxHeap implements max-heap interface -> Option DQuick Check:
Custom heap.Interface needed for max heap [OK]
- Calling heap.Init on a plain slice
- Not implementing Less method for max heap
- Using heap.Push/Pop directly on slice
package main
import (
"container/heap"
"fmt"
)
type MaxHeap []int
func (h MaxHeap) Len() int { return len(h) }
func (h MaxHeap) Less(i, j int) bool { return h[i] > h[j] }
func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *MaxHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
func (h *MaxHeap) Pop() interface{} {
n := len(*h)
x := (*h)[n-1]
*h = (*h)[:n-1]
return x
}
func main() {
arr := []int{4, 1, 7, 3, 8, 5}
h := MaxHeap(arr)
heap.Init(&h)
var kthLargest int
for i := 0; i < 3; i++ {
kthLargest = heap.Pop(&h).(int)
}
fmt.Println(kthLargest)
}
Solution
Step 1: Build max heap from array
Array is [4,1,7,3,8,5]. Max heap root is 8, next largest 7, then 5, etc.Step 2: Pop max 3 times
First pop: 8, second pop: 7, third pop: 5. The 3rd largest is 5.Final Answer:
5 -> Option BQuick Check:
3rd largest element = 5 [OK]
k times; last popped is kth largest [OK]- Confusing 3rd largest with 2nd largest
- Not building max heap correctly
- Off-by-one errors in loop
package main
import (
"container/heap"
"fmt"
)
type MaxHeap []int
func (h MaxHeap) Len() int { return len(h) }
func (h MaxHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *MaxHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
func (h *MaxHeap) Pop() interface{} {
n := len(*h)
x := (*h)[n-1]
*h = (*h)[:n-1]
return x
}
func main() {
arr := []int{10, 20, 15, 30, 40}
h := MaxHeap(arr)
heap.Init(&h)
heap.Pop(&h)
secondLargest := heap.Pop(&h).(int)
fmt.Println(secondLargest)
}
Solution
Step 1: Check Less method for heap type
Less uses < which creates a min heap, but we want a max heap for kth largest.Step 2: Effect on extraction
Extracting twice from min heap gives 10 and 15, not the largest elements.Final Answer:
Less method uses < instead of >, making it a min heap -> Option CQuick Check:
Less method defines heap type [OK]
- Using < in Less for max heap
- Not implementing heap.Interface fully
- Calling heap.Init on plain slice
Solution
Step 1: Compare approaches for large arrays
Building a max heap of entire array is O(n), popping 5 times is O(k log n). Sorting is O(n log n).Step 2: Use min heap of size 5 for efficiency
Maintaining a min heap of size 5 keeps track of top 5 largest elements in O(n log k) time and O(k) space, which is efficient.Final Answer:
Use a min heap of size 5 and replace root when larger element found -> Option AQuick Check:
Min heap size k for kth largest is efficient [OK]
- Building max heap of entire array wastes space/time
- Sorting entire array is slower for large data
- Using hash map does not help with order
Ready to prove it?
Pass the test and this pattern moves unknown
