Last Stone Weight: Simulation on a Max-Heap
This one is a Easy-rated classic reported from Amazon, Google, Zillow interviews: "Last Stone Weight". Like every post in this series, the goal is not memorizing the answer — it is recognizing the Top-K and Heaps pattern on sight. Part 2 of 11 in the Top-K and Heaps arc.
The Problem
Stones have weights; each turn, smash the two heaviest together. Equal weights destroy both; unequal leaves one stone of the difference. Return the last stone's weight, or 0. A warm-up whose real content is the Python max-heap idiom.
Input: stones = [2, 7, 4, 1, 8, 1]
Output: 1
8 and 7 -> 1; 4 and 2 -> 2; 2 and 1 -> 1; 1 and 1 -> 0; one stone of 1 remains.
Recognizing the Top-K and Heaps Pattern
When a problem asks for the k largest, smallest, closest, or most frequent — or for repeated access to an extreme while data changes — a heap gives O(log n) insertion and O(1) access to the extreme. The signature trick: keep a bounded heap of size k with the opposite polarity (a min-heap to track the k largest), evicting the root on overflow. Python's heapq is a min-heap; negate values for max behavior.
Repeatedly take the current maximum from a shrinking collection — the mutation makes sorting once insufficient and a heap exactly right. Python has no built-in max-heap, so store negated values and negate on the way out; write the idiom without ceremony.
The Approach
Heapify the negated weights. While two stones remain, pop twice, push the negated difference when non-zero. Return the negation of the survivor, or 0 for an empty heap.
Each smash removes at least one stone, so at most n − 1 rounds of O(log n) heap work — a bound worth stating because simulation problems invite hand-waving.
Python Solution
import heapq
def last_stone_weight(stones: list[int]) -> int:
"""Weight of the final stone after all smashes, else 0."""
heap = [-s for s in stones] # negate: heapq is a min-heap
heapq.heapify(heap)
while len(heap) > 1:
a = -heapq.heappop(heap) # heaviest
b = -heapq.heappop(heap) # second heaviest
if a != b:
heapq.heappush(heap, -(a - b))
return -heap[0] if heap else 0
Complexity
- Time: O(n log n) — heapify O(n), then up to n − 1 smashes at O(log n)
- Space: O(n) — the heap
Interview Tips and Follow-Ups
- Say why sorting once fails (the difference re-enters at an arbitrary position) — it justifies the heap in one sentence.
- The negation idiom generalizes: for max-heaps of tuples, negate the key field only. Practice it until it costs zero thought.
- Contrast with Last Stone Weight II — same story, but it becomes a subset-sum DP. Same costume, different pattern; recognizing that flip is the lesson.
More Top-K and Heaps problems — and the other eight patterns — live in the Technical Interview category. Drill the pattern, not the problem: that is the entire thesis of this series.
Keep reading
Find Median From a Data Stream With Two Heaps
The two-heap balance: max-heap low half, min-heap high half. Python solution and complexity analysis for the heap and top-k interview pattern.
K Closest Points to Origin Without Square Roots
Bounded max-heap on squared distance — monotone transforms are free. Python solution and complexity analysis for the heap and top-k interview pattern.
Find K Pairs With Smallest Sums: Frontier Expansion
Explore an implicit sorted matrix — seed one row, expand neighbors lazily. Python solution and complexity analysis for the heap and top-k interview pattern.
Newsletter
New posts, straight to your inbox
One email per post. No spam, no tracking pixels, unsubscribe anytime.
Comments
- No comments yet. Be the first.