Editorial
Core insight
Kth Largest Element in an Array · Heap (Priority Queue) Patterns
Core Insight for Kth Largest Element in an Array
The key intuition for the optimal heap solution is that to find the -th largest element, we do not need to keep track of all elements. We only need to maintain a collection of the largest elements seen so far.
If we have a container holding exactly elements, and we encounter a new number from the array:
- If the new number is smaller than the smallest number in our container, it cannot possibly be among the top largest. We ignore it.
- If the new number is larger than the smallest number in our container, the new number deserves a spot in the top . We must remove the "weakest" (smallest) element from the container to make room for the new one.
The Min-Heap is the perfect data structure for this because it provides access to the minimum element (the root) and efficient insertion and deletion.
Visual Description: Imagine a binary tree structure (the Min-Heap) limited to nodes. As we iterate through the array, the heap acts as a filter.
- The root node always holds the minimum value among the current top candidates.
- When a new value
xenters, we comparexto the root. - If
x > root, the root is popped (removed), andxis inserted. The heap rebalances (sifts down) to establish a new minimum at the root. - If the heap size is less than , we simply push
x. - At the end of the process, the root node represents the smallest of the top numbers—which is exactly the definition of the -th largest element.
Deep dive
Full breakdown
Full reasoning, pitfalls, and implementation flow
LeetCode 215: Kth Largest Element in an Array Solution & Explanation
Problem Overview
TL;DR: To solve LeetCode 215, we maintain a Min-Heap of size k to track the top k elements encountered so far; the root of this heap represents the -th largest element.
The problem asks us to identify the -th largest integer in an unsorted array nums. It is important to distinguish this from the -th distinct element; duplicates count towards the ranking. For example, if the input is [3, 3, 3] and k=2, the answer is 3. The problem statement explicitly challenges us to solve this without sorting the entire array, making this a classic interview question for testing data structure proficiency.
Brute Force Approach for Kth Largest Element in an Array
The most intuitive way to solve the Kth Largest Element in an Array is to sort the entire array in descending order and select the element at index k-1 (or sort ascending and select index N-k).
Naive Pseudo-code
function findKthLargest(nums, k):
sort(nums) // Sorts in ascending order
n = length(nums)
return nums[n - k]Complexity Analysis
- Time Complexity: , where is the number of elements in the array. This is dominated by the sorting algorithm (e.g., Timsort or Quicksort).
- Space Complexity: or depending on the specific sorting implementation and whether it operates in-place.
Why this approach is suboptimal
While this solution is correct and often passes online judges, it fails the specific constraint mentioned in the problem description: "Can you solve it without sorting?". In an interview context, solving a selection problem with full sorting is considered inefficient because we perform unnecessary work. We order the entire array when we only care about the relationship between the top k elements and the rest.
Algorithm Strategy: Heap (Priority Queue) Patterns
- Initialize a Min-Heap: Create a priority queue configured as a Min-Heap. This structure will maintain the invariant that it contains the largest elements processed so far.
- Iterate through the Array: Loop through every number in
nums. - Maintain Heap Size:
- Push the current number onto the heap.
- If the size of the heap exceeds
k, remove the smallest element (the root). This step ensures that we discard the elements that are too small to be in the topk.
- Result: After iterating through the entire array, the Min-Heap will contain exactly
kelements. The element at the top of the Min-Heap is the smallest of thesekgiants, effectively making it the -th largest element of the entire array.
Execution Flow
Consider nums = [3, 2, 1, 5, 6, 4] and k = 2.
- Initialize: Min-Heap
pq = []. - Process 3: Push
3. Heap:[3]. Size is 1 (). - Process 2: Push
2. Heap:[2, 3]. Size is 2 (). - Process 1: Push
1. Heap:[1, 2, 3]. Size is 3 (). Pop min (1). Heap:[2, 3].- Logic:
1is smaller than the current top 2 (2and3), so it is discarded.
- Logic:
- Process 5: Push
5. Heap:[2, 3, 5]. Size is 3 (). Pop min (2). Heap:[3, 5].- Logic:
5is larger than2.2is no longer in the top 2.
- Logic:
- Process 6: Push
6. Heap:[3, 5, 6]. Size is 3 (). Pop min (3). Heap:[5, 6].- Logic:
6enters,3is evicted.
- Logic:
- Process 4: Push
4. Heap:[4, 5, 6]. Size is 3 (). Pop min (4). Heap:[5, 6].- Logic:
4is smaller than5and6. It enters momentarily but is immediately the smallest, so it is popped.
- Logic:
- Result: The top of the heap is
5. Correct.
Proof of Correctness
The algorithm maintains the invariant that at step , the heap contains the largest elements from the subarray nums[0...i].
- Base Case: For the first elements, the heap simply stores them all.
- Inductive Step: Assume the heap contains the largest elements of
nums[0...i-1]. Let be the root of the heap. When we processnums[i]:- If
nums[i] <= min_top_k, thennums[i]is not larger than any of the current top . It correctly does not displace any element (or it displaces itself immediately). - If
nums[i] > min_top_k, thennums[i]is strictly larger than the smallest of the top . Therefore,min_top_kis no longer in the top set for the subarraynums[0...i]. We removemin_top_kand includenums[i], restoring the invariant.
- If
By induction, after processing elements, the heap contains the largest elements of the entire array. The root is the minimum of this set, which corresponds to the -th largest value.
Pattern Reuse Notes
The Heap - Top K Elements pattern used in this LeetCode 215 Solution is highly versatile. It applies directly to several other popular interview questions:
- LeetCode 347: Top K Frequent Elements - Instead of element values, we push (frequency, value) pairs into the Min-Heap.
- LeetCode 451: Sort Characters By Frequency - Similar to Top K Frequent, but we construct a string from the heap results.
- LeetCode 506: Relative Ranks - Uses a heap to map scores to ranks (Gold, Silver, Bronze).
- LeetCode 703: Kth Largest Element in a Stream - This is the "live" version of LeetCode 215 where the array grows dynamically; the Min-Heap approach is the standard optimal solution here.
Feynman coach · Before you peek at the code
Can you explain the core insight in your own words?
If you can explain it before reading code, you’re far more likely to recall it under interview pressure.
Reference Implementation
C++ Solution for LeetCode 215
1#include <vector>
2#include <queue>
3
4class Solution {
5public:
6 int findKthLargest(std::vector<int>& nums, int k) {
7 // Min-heap to store the top k elements
8 // std::priority_queue is a max-heap by default, so we use greater<int>
9 std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
10
11 for (int num : nums) {
12 minHeap.push(num);
13
14 // If heap size exceeds k, remove the smallest element
15 if (minHeap.size() > k) {
16 minHeap.pop();
17 }
18 }
19
20 // The root of the min-heap is the kth largest element
21 return minHeap.top();
22 }
23};Java Solution for LeetCode 215
1import java.util.PriorityQueue;
2
3class Solution {
4 public int findKthLargest(int[] nums, int k) {
5 // Java's PriorityQueue is a Min-Heap by default
6 PriorityQueue<Integer> minHeap = new PriorityQueue<>();
7
8 for (int num : nums) {
9 minHeap.add(num);
10
11 // Maintain exactly k elements in the heap
12 if (minHeap.size() > k) {
13 minHeap.poll();
14 }
15 }
16
17 // The top of the heap is the kth largest element
18 return minHeap.peek();
19 }
20}Python Solution for LeetCode 215
1import heapq
2
3class Solution:
4 def findKthLargest(self, nums: list[int], k: int) -> int:
5 min_heap = []
6
7 for num in nums:
8 # Push the current number onto the heap
9 heapq.heappush(min_heap, num)
10
11 # If the heap grows larger than k, remove the smallest element
12 if len(min_heap) > k:
13 heapq.heappop(min_heap)
14
15 # The smallest element in the heap of size k is the kth largest overall
16 return min_heap[0]