150NeetCode 150

64.Kth Largest Element in a Stream

EasyHeap / Priority Queue ยท 1/7

Problem

Design a class that tracks the k-th largest element of a growing stream of numbers (the k-th largest in sorted order, so duplicates count separately).

  • KthLargest(int k, int[] nums) initializes with k and the initial numbers.
  • int add(int val) appends val to the stream and returns the current k-th largest element.

Examples

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: After add(3) the stream is [2,3,4,5,8]; the 3rd largest is 4.
             After add(5): [2,3,4,5,5,8] -> 5. After add(10): -> 5. After add(9): -> 8. After add(4): -> 8.
Input:  ["KthLargest","add","add","add"]
        [[1,[]],[-3],[-2],[-4]]
Output: [null,-3,-2,-2]
Explanation: With k = 1 we always return the maximum seen so far.

Constraints

  • 0 <= nums.length <= 10^4
  • 1 <= k <= nums.length + 1
  • -10^4 <= nums[i], val <= 10^4
  • At most 10^4 calls to add.
  • It is guaranteed there are at least k elements when add returns.

๐Ÿ’ก Key Insight

Only the top k values ever matter; anything smaller than the current k-th largest can never become the answer again. Keep those k values in a min-heap: its root is the smallest of the top k, which is exactly the k-th largest. Each add is one push and at most one pop โ€” O(log k).

Brute Force (Sort on Every Add)

TimeO(n log n) per add, where n is the stream length so far.SpaceO(n)

Intuition

Store everything in a list. On each add, append, sort, and read index size - k.

Algorithm

  1. Constructor: copy nums into a list.
  2. add(val): append val, sort the list ascending.
  3. Return list.get(list.size() - k).

Visualization

k = 3, list = [4,5,8,2]
add(3): [2,3,4,5,8]   size-k = 2 -> 4
add(5): [2,3,4,5,5,8] size-k = 3 -> 5

Code

java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class KthLargest {
    private final int k;
    private final List<Integer> list = new ArrayList<>();

    public KthLargest(int k, int[] nums) {
        this.k = k;
        for (int num : nums) {
            list.add(num);
        }
    }

    public int add(int val) {
        list.add(val);
        Collections.sort(list); // full sort every time
        return list.get(list.size() - k);
    }
}

Complexity

  • Time: O(n log n) per add, where n is the stream length so far.
  • Space: O(n) โ€” every element is kept.

Complexity Comparison

Approach Time per add Space
Sort on Every Add O(n log n) O(n)
Sorted List + Binary Insertion O(n) O(n)
Min-Heap of Size k O(log k) O(k)

Common Pitfalls

  • Using a max-heap: the k-th largest would then be buried inside the heap, not at the root.
  • Forgetting that nums may have fewer than k elements initially โ€” do not poll until the size exceeds k, and do not assume the heap is full in the constructor.
  • Trimming only in add but not in the constructor โ€” leaves extra elements so peek() returns a smaller value.
  • Deduplicating values: [5,5,8] with k = 2 has 5 as the 2nd largest, so duplicates must stay.