AlgoMaster Logo

Last Stone Weight

easyFrequency4 min readUpdated June 23, 2026

Understanding the Problem

We simulate a process: repeatedly pick the two heaviest stones, smash them, and put the result back if anything remains. This continues until one or zero stones are left.

The work each round is to find the two largest elements. After removing them and possibly inserting a new value, we need the two largest again. Sorting every round solves this, but a max-heap (priority queue) supports repeated extraction of the maximum at lower cost.

Key Constraints:

  • 1 <= stones.length <= 30 → The input is small, so an O(n^2 log n) approach also passes. The constraint does not rule out any of the approaches below; it only means the simulation always terminates quickly.
  • 1 <= stones[i] <= 1000 → All weights are positive integers. The difference y - x is always non-negative, and the smashed value y - x < y, so the maximum weight never increases and the heap or list strictly shrinks (one stone removed each round). The simulation runs at most n - 1 rounds.

Approach 1: Sorting

Intuition

Sorting the array puts the two heaviest stones at the end. We smash them, compute the difference, remove both, and if the difference is non-zero, insert it back. Then we sort again and repeat until one or zero stones remain.

This re-sorts the whole array every round, which is wasteful, but with n up to 30 it runs fast and is easy to reason about.

Algorithm

  1. While the list has more than one stone:
    • Sort the list.
    • Take the last two elements (the two heaviest).
    • Remove them both from the list.
    • If they are not equal, add the difference back to the list.
  2. If one stone remains, return its weight. Otherwise, return 0.

Example Walkthrough

1Initial stones array
0
2
1
7
2
4
3
1
4
8
5
1
1/6

Code

Sorting the entire list every round to find two elements is the bottleneck. A max-heap keeps the maximum accessible without re-sorting, which removes that cost.

Approach 2: Max-Heap (Optimal)

Intuition

A max-heap supports extracting the maximum in O(log n) and inserting a new element in O(log n). Instead of sorting every round, we build the heap once, then repeatedly extract the two largest, smash them, and push the result back. Each round costs O(log n) instead of O(n log n) for a full re-sort.

The default heap direction differs by language. C++ priority_queue and Rust BinaryHeap are max-heaps. Java PriorityQueue and C# PriorityQueue are min-heaps, so we either pass a reverse comparator or use a negated priority. Python heapq is a min-heap, so we negate the stored values: push -stone, and negate again when popping to recover the original weight.

Algorithm

  1. Build a max-heap from all the stones.
  2. While the heap has more than one element:
    • Extract the two largest values (y and x, with y >= x).
    • If y != x, push (y - x) back into the heap.
  3. If the heap has one element, return it. Otherwise, return 0.

Example Walkthrough

1Build max-heap from [2, 7, 4, 1, 8, 1]
8max71241
1/9

Code