Learning/Heap Priority Queue

Heap / Priority Queue

7 questions. A heap maintains one weak guarantee — parent before children — and that's exactly enough to expose an extreme in O(1) while costing only O(log n) to update.

The one idea

Sorting gives you complete order for O(n log n). If you only ever need the minimum (or the maximum), that's far more than you're paying for.

OperationCost
See the extremeO(1)
InsertO(log n)
Remove the extremeO(log n)
Find an arbitrary elementO(n) — there's no order to exploit

That last row is the price. A heap is useless for lookup, and that's why removing a specific value is the recurring pain point in the follow-ups.

The inversion that trips everyone up

To keep the k largest, use a min-heap of size k
To keep the k largest, use a min-heap of size k

Min-heap for the k LARGEST. Max-heap for the k SMALLEST.

The heap is always inverted relative to the wording, because the root is the eviction candidate, not the answer. Keeping the k largest means the thing to discard is the smallest of them — so that's what must sit at the root.

Questions 1, 3 and 4 are all this same move.

When a heap is NOT the answer

Two of the seven have better solutions, which is worth knowing before reaching for a PriorityQueue reflexively:

Question 4 — with the whole array in memory, quickselect is O(n) average versus the heap's O(n log k).

Three approaches, three trades
Three approaches, three trades

Question 5 — the greedy heap simulation is correct but does work proportional to the answer, which can dwarf the input. The frequency formula is O(n).

The most frequent task dictates the layout
The most frequent task dictates the layout

The heap wins when data streams, when k ≪ n, or when the collection changes between extractions.

Two heaps for the median

Two heaps facing each other
Two heaps facing each other

A heap exposes an extreme; the median is the element furthest from both extremes. Split the data at the median and each half's adjacent element becomes an extreme.

The add is three unconditional lines — offer to the max-heap, push its root across to the min-heap, then rebalance. The routing enforces the ordering, so there are no comparisons and no boundary cases. The order matters: rebalancing before transferring can break the invariant.

The traps

TrapSymptom
Max-heap for the k largest (Q1, Q4)The element you need is buried at a leaf
TreeSet instead of a heap (Q1)Duplicates collapse — silently wrong rank
Pushing a zero stone (Q2)A phantom stone can be returned as the answer
!isEmpty() instead of size() > 1 (Q2)poll() returns null → NPE on unboxing
Computing (Q3)Needless floating point; x² + y² orders identically
k - 1 instead of n - k (Q4)Plausible wrong answer, not a crash
Deterministic pivot (Q4)O(n²) on sorted input — measured 595× worse
Formula without max(tasks.length, …) (Q5)Undercounts when the gaps overflow
List instead of Set for follows (Q6)Double-follow duplicates tweets in the feed
Forgetting self-inclusion (Q6)Your own tweets silently vanish from your feed
/ 2 instead of / 2.0 (Q7)1.5 truncates to 1.0

Java notes

Java
new PriorityQueue<>()                              // min-heap (the default)
new PriorityQueue<>(Comparator.reverseOrder())     // max-heap
new PriorityQueue<>(existingCollection)            // O(n) heapify — natural ordering only

Verification

Every snippet compiled and cross-checked against an independent implementation — 3,000+ randomized cases:

Four deliberately-broken variants confirm the traps: