Description
Kth Largest Element in a Stream
You are part of a university admissions office and need to keep track of the kth highest test score from applicants in real-time. This helps to determine cut-off marks for interviews and admissions dynamically as new applicants submit their scores.
You are tasked to implement a class which, for a given integer k, maintains a stream of test scores and continuously returns the kth highest test score after a new score has been submitted. More specifically, we are looking for the kth highest score in the sorted list of all scores.
Implement the KthLargest class:
KthLargest(int k, int[] nums)Initializes the object with the integerkand the stream of test scoresnums.int add(int val)Adds a new test scorevalto the stream and returns the element representing thekthlargest element in the pool of test scores so far.
Example 1:
Input:
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
Output: [null, 4, 5, 5, 8, 8]
Explanation:
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3); // return 4
kthLargest.add(5); // return 5
kthLargest.add(10); // return 5
kthLargest.add(9); // return 8
kthLargest.add(4); // return 8
Example 2:
Input:
["KthLargest", "add", "add", "add", "add"]
[[4, [7, 7, 7, 7, 8, 3]], [2], [10], [9], [9]]
Output: [null, 7, 7, 7, 8]
Explanation:
KthLargest kthLargest = new KthLargest(4, [7, 7, 7, 7, 8, 3]);
kthLargest.add(2); // return 7
kthLargest.add(10); // return 7
kthLargest.add(9); // return 7
kthLargest.add(9); // return 8
Constraints:
0 <= nums.length <= 1041 <= k <= nums.length + 1-104 <= nums[i] <= 104-104 <= val <= 104- At most
104calls will be made toadd.
Primary Approach: Min-Heap of Size ( Time per Add, Space)
Intuition
To find the -th largest element in a stream, we only care about maintaining the top largest numbers seen so far. A Min-Heap (PriorityQueue) of size is the ideal data structure:
- Min-Heap Property: The smallest element among the top elements always stays at the root (
minHeap.peek()). - -
thLargest Definition: The smallest of the largest elements is precisely the -thlargest element overall. - Execution:
add(val): PushvalintominHeap. IfminHeap.size()exceeds , evict the smallest element (minHeap.poll()).- Return
minHeap.peek(), which guarantees the -thlargest value in lookup time.
import java.util.PriorityQueue;
class KthLargest {
private final PriorityQueue<Integer> minHeap;
private final int k;
public KthLargest(int k, int[] nums) {
this.k = k;
this.minHeap = new PriorityQueue<>();
// Add initial array elements to the stream
for (int num : nums) {
add(num);
}
}
public int add(int val) {
minHeap.offer(val);
// Maintain heap size of at most k
if (minHeap.size() > k) {
minHeap.poll();
}
return minHeap.peek();
}
}
Complexity
- Time Complexity:
- Constructor: — Inserting initial elements into a heap bounded by size .
add(val): — Pushing and popping from a heap containing at most elements.
- Space Complexity: — Min-heap stores at most elements at any point.
Key Interview Discussion Points
-
Why Min-Heap instead of Max-Heap?
-
A Max-Heap would require storing all stream elements ( elements), taking space and time per
add()call. -
A Min-Heap of size discards all elements smaller than the -
thlargest, reducing space to and operation time to , which is significantly faster for large streams (). -
Handling Initial Array Edge Case: The problem allows
nums.length < kinitially. By routing initial items throughadd(),minHeap.poll()will only trigger once the heap size exceeds , ensuring safety whennumsstarts out empty or small.
Easy Memory Rule
“Finding -
thLARGEST? Use a MIN-HEAP of sizeminHeap.peek()always gives the answer!”