Skip to main content

LeetCode Patterns

Two Heaps Pattern

The Two Heaps pattern maintains a max-heap for the lower half of a stream of values and a min-heap for the upper half, balanced so their sizes differ by at most one. It answers running-median, sliding-window-median, and IPO-style scheduling problems in O(log n) per insert with O(n) total space.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Complexity

Time
O(log n)
Space
O(n)

When to use Two Heaps

  • You need to maintain the median of a stream of numbers as new values arrive.
  • You need to track the running median of a sliding window over an array.
  • The problem asks for the smallest k elements out of one set combined with the largest k elements out of another.
  • You repeatedly pick from two separate ordered collections and need the cheapest or most valuable element on each turn.
  • You can split data into a `low` half and a `high` half and query the boundary value in O(1).

Template

class MedianFinder {
  constructor() {
    this.low = new MaxHeap();
    this.high = new MinHeap();
  }
  addNum(num) {
    if (this.low.size === 0 || num <= this.low.peek()) {
      this.low.push(num);
    } else {
      this.high.push(num);
    }
    if (this.low.size > this.high.size + 1) this.high.push(this.low.pop());
    if (this.high.size > this.low.size) this.low.push(this.high.pop());
  }
  findMedian() {
    if (this.low.size > this.high.size) return this.low.peek();
    return (this.low.peek() + this.high.peek()) / 2;
  }
}

Example LeetCode problems

#ProblemDifficultyFrequency
295Find Median from Data Streamhardcompany favorite
480Sliding Window Medianhardfrequently asked
502IPOhardclassic
436Find Right Intervalmediumless common
502Maximize Capitalhardclassic

Common mistakes

  • Forgetting to invert comparisons when implementing a max-heap on top of a standard min-heap library, leading to a min-of-min instead of max-of-low.
  • Letting the size difference grow beyond one — the median is only readable in O(1) when the heaps are balanced.
  • Returning the wrong heap's top on even total counts; the answer is the average of both tops, not just one.
  • Mixing integer and float division when computing the average median, which truncates the result in some languages.
  • On Sliding Window Median, lazily deleting outgoing elements without a synced count, leading to a heap top that no longer belongs to the window.

Frequently asked questions

Why use two heaps instead of one sorted list?

A sorted list supports O(1) median lookup but O(n) insertion. Two heaps support O(log n) insertion AND O(1) median lookup at the cost of slightly more code. For streaming data with many inserts, the heap version is the only viable choice.

How do I implement a max-heap if my language only ships a min-heap?

Negate the values on push and pop (Python's heapq, Java's PriorityQueue with a reverse comparator). Some languages provide an explicit max-heap class — check before reimplementing.

Why does the lower half use a max-heap and not a min-heap?

You need O(1) access to the largest value of the lower half (that's the median or one of the two middle values). A max-heap puts the largest element of its contents at the root, so peek is O(1).

How do I handle deletion for sliding-window median?

Most implementations use lazy deletion: keep a hash map of pending removals and pop the heap top whenever it matches an entry. After every operation, normalize the heap roots by popping any lazily-deleted elements off the top.

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

Practice these live with InterviewChamp.AI

Drill the Two Heaps pattern under real interview conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →