Chaturmind
LearnDSASystem DesignBlogPremium
Sign inGet started
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML

Company

  • Blog
  • Premium
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Interview Coding Patterns

Core Patterns

  • Fast & Slow Pointers
  • Merge Intervals
  • Cyclic Sort

Heap & Priority Queue Patterns

  • Top-K Elements
  • K-Way Merge
  • Two Heaps
Chaturmind
← Interview Coding Patterns

Core Patterns

  • Fast & Slow Pointers
  • Merge Intervals
  • Cyclic Sort

Heap & Priority Queue Patterns

  • Top-K Elements
  • K-Way Merge
  • Two Heaps
HomeLearnDSADSA Patterns for InterviewsCoding Patterns
✓ FreeAdvanced· 12 min read

Two Heaps Pattern

Use a max-heap and min-heap together to find medians dynamically and solve scheduling problems.

Published March 25, 2025


Two Heaps Pattern

The two-heaps pattern maintains a max-heap for the lower half and a min-heap for the upper half of a sorted dataset. This gives O(1) median access and O(log n) insertion.

Find Median from Data Stream

class MedianFinder {
    private PriorityQueue<Integer> lower = new PriorityQueue<>(Collections.reverseOrder()); // max-heap
    private PriorityQueue<Integer> upper = new PriorityQueue<>(); // min-heap

    public void addNum(int num) {
        lower.offer(num);               // always add to lower first
        upper.offer(lower.poll());      // balance: move max of lower to upper
        if (upper.size() > lower.size()) // keep lower >= upper in size
            lower.offer(upper.poll());
    }

    public double findMedian() {
        if (lower.size() > upper.size())
            return lower.peek(); // odd total: median is max of lower
        return (lower.peek() + upper.peek()) / 2.0; // even: average of two middles
    }
}

// Example:
// addNum(1): lower=[1], upper=[]
// addNum(2): lower=[1], upper=[2]
// findMedian() = (1+2)/2 = 1.5
// addNum(3): lower=[2,1], upper=[3]
// findMedian() = 2

Sliding Window Median

public double[] medianSlidingWindow(int[] nums, int k) {
    TreeMap<Integer, Integer> lower = new TreeMap<>(); // simulates max-heap
    TreeMap<Integer, Integer> upper = new TreeMap<>();
    // ... (implementation using TreeMap for O(log k) remove)
    double[] result = new double[nums.length - k + 1];
    // Full implementation uses a balance counter and TreeMap for O(log k) deletes
    return result;
}

IPO — Maximize Capital

// Pick k projects to maximize capital
// Two heaps: max-heap by profit for affordable projects, min-heap by capital for all projects
public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
    int n = profits.length;
    PriorityQueue<int[]> locked = new PriorityQueue<>((a,b) -> a[0]-b[0]); // min-heap by capital
    PriorityQueue<int[]> available = new PriorityQueue<>((a,b) -> b[1]-a[1]); // max-heap by profit

    for (int i = 0; i < n; i++) locked.offer(new int[]{capital[i], profits[i]});

    for (int i = 0; i < k; i++) {
        // Unlock all projects we can afford
        while (!locked.isEmpty() && locked.peek()[0] <= w)
            available.offer(locked.poll());
        if (available.isEmpty()) break;
        w += available.poll()[1]; // pick most profitable
    }
    return w;
}

Why Two Heaps?

         lower (max-heap)  |  upper (min-heap)
  ... 1, 2, 3, [4]        |  [5], 6, 7, 8 ...
                  ↑ median(s) ↑
  • Max of lower = 4 (O(1))
  • Min of upper = 5 (O(1))
  • Median = 4 (odd) or (4+5)/2 = 4.5 (even)

Insertion is O(log n); median query is O(1).

Balance Invariant

Always maintain: lower.size() == upper.size() or lower.size() == upper.size() + 1

This ensures the median is always at the top of one or both heaps.

Interview Tips

  1. The two-heap median is a very common hard interview problem — know it cold.
  2. The key insight: after every insertion, re-balance so neither heap is more than 1 element larger.
  3. For sliding window median: use TreeMap<Integer, Integer> with a multiplicity count to support O(log k) removal of arbitrary elements.

Previous

K-Way Merge

AI Tutor

Lesson: Two Heaps Pattern

Quick actions

AI responses can be inaccurate. Verify critical information.