−65% Most banks now $169 $59.
Coding · 9 min read

Point72's Streaming Median Question

Point72's coding rounds often start with a clean streaming problem and then squeeze the resources until the exact answer stops fitting. The median of a data stream is the classic: two heaps to start, then a memory limit, then many machines. Here is the full question, Java for each part, and a detailed rubric.


The question

Numbers arrive one at a time. Support addNum and findMedian at any point.

Part 2: the stream is too large to store; find the median under a fixed memory budget. Part 3: the data is split across many machines; produce a global median.

Part 1 · Two heaps

Hold the lower half in a max-heap and the upper half in a min-heap, kept balanced to within one element. The median is the top of the larger heap, or the average of the two tops. Insert is O(log n), read is O(1).

import java.util.*;

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

    void addNum(int num) {
        low.offer(num);
        high.offer(low.poll());                 // pass the largest of the low half up
        if (high.size() > low.size()) low.offer(high.poll());   // keep low >= high in size
    }

    double findMedian() {
        if (low.size() > high.size()) return low.peek();
        return (low.peek() + (double) high.peek()) / 2.0;
    }
}

Part 2 · Bounded memory, approximate

If you cannot keep every number, keep a fixed-size histogram instead. Each value increments one bucket; the median is the bucket where the cumulative count crosses half. Memory is constant in the number of buckets, independent of the stream length, at the cost of bucket-width error.

class ApproxMedian {
    private final double lo, width; private final long[] buckets; private long count;

    ApproxMedian(double lo, double hi, int numBuckets) {
        this.lo = lo; this.width = (hi - lo) / numBuckets; this.buckets = new long[numBuckets];
    }

    void add(double x) {
        int b = (int) ((Math.min(Math.max(x, lo), lo + width * buckets.length) - lo) / width);
        if (b == buckets.length) b--;           // clamp the top edge
        buckets[b]++; count++;
    }

    double median() {
        long target = (count + 1) / 2, cum = 0;
        for (int b = 0; b < buckets.length; b++) {
            cum += buckets[b];
            if (cum >= target) return lo + (b + 0.5) * width;   // bucket midpoint estimate
        }
        return lo + width * buckets.length;
    }
}

For unknown or long-tailed ranges, a t-digest is the better sketch: it keeps more resolution near the median and bounds memory by the number of centroids. The histogram is the version you can write on a whiteboard in two minutes.

Part 3 · Merge across machines

The histogram is mergeable. Each machine builds one over the same bucketing, then you sum the bucket arrays element-wise and read the median off the combined histogram. T-digests merge the same way by combining centroids, which is why these sketches are the standard answer for distributed quantiles.

// Combine partial histograms (same lo, hi, numBuckets) into a global estimate.
static long[] merge(long[] a, long[] b) {
    long[] out = new long[a.length];
    for (int i = 0; i < a.length; i++) out[i] = a[i] + b[i];
    return out;                                  // read the median off 'out' as in Part 2
}

How Point72 scores it

Dimension Weak Strong
Heap invariantHeaps drift out of balanceSizes within one, low holds the median side
Median readWrong on even or odd countsTop of larger heap, or average of tops
ComplexitySorts on each queryO(log n) insert, O(1) median
Bounded memoryTries to store the whole streamFixed histogram or t-digest, constant memory
Accuracy trade-offClaims the estimate is exactNames bucket-width error and t-digest for tails
Distributed mergeCannot combine machinesSums mergeable sketches into a global median

This is one question of 13 pages

Get the full Point72 question bank

The full Point72 bank carries the coding, C++ design, and quant rounds, each problem with its follow-ups and a rubric, compiled from people familiar with the process and cross-verified across sources.

Point72 interview FAQ

What does the Point72 coding interview ask?+

Streaming algorithms, heaps, dynamic programming, and C++ design. The median-of-a-stream question tests the two-heap invariant, then how you approximate under memory limits and merge results across machines.

How do you find the median of a data stream?+

Keep a max-heap of the lower half and a min-heap of the upper half, balanced so their sizes differ by at most one. Insertion is O(log n) and the median is read from the heap tops in O(1).

How do you find a median when the data does not fit in memory?+

Approximate it: a fixed-bucket histogram or a t-digest gives a bounded-memory estimate, and these sketches merge across machines, so you can compute an approximate global median from partial streams.

Where can I find real Point72 interview questions?+

Pichup maintains a 13-page Point72 Asset Management question bank compiled from people familiar with the process, with the coding, C++ design, and quant rounds, their follow-ups, and rubrics. The question in this guide is one of them.