Kth Largest Element In An Array
Difficulty: Medium Source: NeetCode
Problem
Given an integer array
numsand an integerk, return thekth largest element in the array.Note that it is the
kth largest element in sorted order, not thekth distinct element.Can you solve it without sorting?
Example 1: Input:
nums = [3, 2, 1, 5, 6, 4],k = 2Output:5Example 2: Input:
nums = [3, 2, 3, 1, 2, 4, 5, 5, 6],k = 4Output:4Constraints:
1 <= k <= nums.length <= 10^5-10^4 <= nums[i] <= 10^4
Prerequisites
Before attempting this problem, you should be comfortable with:
- Heaps / Priority Queues — min-heap of bounded size
- QuickSelect — partition-based selection algorithm (same idea as quicksort but only recurse on one side)
- Python’s
heapqmodule —heappush,heappop
1. Brute Force — Sort
Intuition
Sort the array in descending order and return the element at index k - 1. Dead simple and fast enough for most practical cases — just not O(n).
Algorithm
- Sort
numsin descending order. - Return
nums[k - 1].
Solution
def findKthLargest(nums, k):
nums.sort(reverse=True)
return nums[k - 1]
print(findKthLargest([3, 2, 1, 5, 6, 4], 2)) # 5
print(findKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)) # 4
print(findKthLargest([1], 1)) # 1
Complexity
- Time:
O(n log n) - Space:
O(1)(in-place sort)
2. Min-Heap of Size K
Intuition
Keep a min-heap of exactly k elements. As we stream through nums, if the heap has fewer than k elements we push freely. Once it’s full, only push the new element if it’s larger than the heap’s minimum — and in that case pop the minimum first to keep the heap at size k. At the end, heap[0] is the kth largest.
Algorithm
- Initialize an empty heap.
- For each
numinnums: a. Pushnum. b. Iflen(heap) > k, pop the minimum. - Return
heap[0].
Solution
import heapq
def findKthLargest(nums, k):
heap = []
for num in nums:
heapq.heappush(heap, num)
if len(heap) > k:
heapq.heappop(heap)
return heap[0]
print(findKthLargest([3, 2, 1, 5, 6, 4], 2)) # 5
print(findKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)) # 4
print(findKthLargest([1], 1)) # 1
Complexity
- Time:
O(n log k) - Space:
O(k)
3. QuickSelect — O(n) Average
Intuition
QuickSelect is like quicksort, but we only recurse into the partition that contains our target index. We pick a pivot, partition the array so all elements greater than the pivot come first, then check: if the pivot lands at index k - 1 we’re done; otherwise recurse left or right. On average this touches n + n/2 + n/4 + ... ≈ 2n elements.
Algorithm
- Pick a pivot (we’ll use the last element for simplicity).
- Partition: move all elements greater than the pivot to the left side. Track the boundary index
p. - If
p == k - 1, returnnums[p]. - If
p < k - 1, recurse on the right partition with the samek. - If
p > k - 1, recurse on the left partition with the samek.
Solution
import random
def findKthLargest(nums, k):
def quickselect(left, right, k_idx):
# Randomize pivot to avoid worst-case O(n²)
pivot_idx = random.randint(left, right)
nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]
pivot = nums[right]
# Partition: elements > pivot go to the left
p = left
for i in range(left, right):
if nums[i] > pivot:
nums[p], nums[i] = nums[i], nums[p]
p += 1
nums[p], nums[right] = nums[right], nums[p]
if p == k_idx:
return nums[p]
elif p < k_idx:
return quickselect(p + 1, right, k_idx)
else:
return quickselect(left, p - 1, k_idx)
return quickselect(0, len(nums) - 1, k - 1)
print(findKthLargest([3, 2, 1, 5, 6, 4], 2)) # 5
print(findKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)) # 4
print(findKthLargest([1], 1)) # 1
Complexity
- Time:
O(n)average,O(n²)worst case (mitigated by random pivot) - Space:
O(n)worst case recursion stack (use iterative version to getO(1))
Common Pitfalls
Confusing kth largest with kth smallest. The kth largest in a descending sort is at index k - 1, or equivalently the kth smallest in an ascending sort is at index n - k. It’s easy to mix these up — be explicit about your sort direction.
QuickSelect worst case without randomization. A sorted input kills naive QuickSelect when always picking the last element as pivot. Always shuffle or pick a random pivot.
Heap of size k returns heap[0] (the minimum of the top-k). That minimum is the kth largest — not the overall minimum. Students sometimes confuse this and try max(heap) instead.