~/problems / Heaps / Heaps and priority queues

Last Stone Weight

easy ~15 min

A quarry crusher repeatedly grabs the two heaviest rocks left in the pile and smashes them together:

  • if they weigh the same, both turn to dust and disappear;
  • otherwise the lighter one is destroyed and the heavier one loses that much weight (a rock of weight a hitting one of weight b <= a leaves a rock of weight a - b), which goes back on the pile.

This repeats until at most one rock is left. Write last_rock(weights) -> int that returns the weight of the remaining rock, or 0 if nothing is left.

last_rock([3, 8, 2, 6, 1])   # 0   (8,6 -> 2; 3,2 -> 1; 2,1 -> 1; 1,1 -> dust)
last_rock([10, 4])           # 6
last_rock([9])               # 9
last_rock([5, 5, 5])         # 5

Constraints:

  • 1 <= len(weights) <= 2 * 10^5; each weight is in [1, 10^9].
  • Re-sorting the pile before every smash is O(n² log n) overall, far too slow here. Aim for O(n log n).
Show hint

Each round only needs the two largest values, and the leftover goes straight back in. Use a structure that hands you the current maximum in O(log n) and accepts insertions just as cheaply.

Topic: Heaps and priority queues. heapq: top-k, k-way merge, two heaps for a running median.

Read the visual guide
0:00
Ctrl ' run · Ctrl ↵ submit
esc