Kth Largest Element asks for the kth biggest number in an unsorted array. The clean interview answer is a min-heap of size k — a tiny priority queue that quietly keeps only the k largest numbers around.
Problem. Given an integer array nums and an integer k, return the kth largest element in the
array. Note this is the kth largest in sorted order, not the kth distinct element.
Example: nums = [3, 2, 1, 5, 6, 4], k = 2 → answer 5 (sorted descending: 6, 5, 4, 3, 2, 1, and the 2nd is 5).
The slow way first
The obvious idea: sort the array descending and return index k - 1. That works and is easy to write, but sorting is O(n log n) and throws away the fact that we only care about k numbers, not all n.
The question to ask: do I really need the whole array in order? No — I only need to track the k largest numbers as they go by, and among those the smallest one is the answer.
The idea: a min-heap of size k
Keep a min-heap (a priority queue whose smallest element is always on top). Walk the array and push every number. Whenever the heap grows past size k, pop the smallest — it cannot possibly be one of the k largest. After the scan, the heap holds exactly the k largest numbers, and its root (the minimum of those) is the kth largest.
The key insight: the heap never holds more than k items, so a push/pop costs O(log k), not O(log n). The root is the k-th largest because everything below the top k has already been popped away.
Walk through it
Step through the animation. The pointer num scans the input left to right; the strip below is the heap (drawn smallest-on-the-left so the root is visible). Watch size 3 appear after pushing 1, 5, 6, and 4 — each time we immediately pop the root to shrink back to k = 2. When the scan ends the heap is [5, 6], so the root 5 is the answer.
Pseudocode
make an empty min-heap
for each num in nums:
push num onto the heap
if the heap now has more than k items:
pop the smallest (the root)
return the heap's root # smallest of the k largest = kth largestThe Python solution
import heapq
def find_kth_largest(nums, k):
heap = []
for num in nums:
heapq.heappush(heap, num)
if len(heap) > k:
heapq.heappop(heap)
return heap[0]- Python's
heapqis a min-heap:heap[0]is always the smallest element. heappushadds a number;heappopremoves and returns the smallest — both O(log k) since the heap stays at size k.- The
if len(heap) > kguard is the whole trick: we let the heap grow by one, then drop the smallest, so only the k largest survive. - After the loop,
heap[0]is the smallest of the k largest — exactly the kth largest.
Complexity
| Case | Time | Notes |
|---|---|---|
| Sort then index | O(n log n) (moderate) | simple but sorts everything |
| Min-heap of size k | O(n log k) (moderate) | n pushes/pops on a size-k heap |
| Quickselect (avg) | O(n) (moderate) | partition-based, O(n²) worst case |
O(k) (moderate)The heap uses only O(k) extra space. For small k this beats sorting handily. If you need the absolute fastest average case, quickselect finds the kth largest in O(n) on average by partitioning around a pivot — but it degrades to O(n²) in the worst case, so the heap is the safer interview default.
When this pattern shows up
Any time a problem says "top k" or "kth largest / smallest," reach for a heap of size k. Top K Frequent Elements, K Closest Points to Origin, and merging k sorted lists are all the same move: keep a bounded heap instead of sorting the whole input.
Use the right heap direction. For the kth largest, keep a min-heap (pop the smallest). It feels backwards, but a min-heap lets you cheaply evict the weakest of your current top k.
Practice
With nums = [3, 2, 1, 5, 6, 4] and k = 2, right after pushing 5 the heap is [2, 3, 5]. What gets popped, and what is the heap afterward?
1. Why use a min-heap to find the kth LARGEST element?
2. Why is each push/pop O(log k) instead of O(log n)?
3. After the full scan, where is the answer?
4. What is the average-case time of quickselect for this problem?