You have a collection of stones, each with a positive integer weight. Each turn, choose the two heaviest stones and smash them together. Suppose the heaviest is a and the second heaviest is b. If a == b both are destroyed; if a != b, stone of weight a is destroyed and stone of weight b becomes a - b. Return the weight of the last remaining stone, or 0 if none remain.
stones = [2,7,4,1,8,1]1stones = [1]1stones = [3,3]0PriorityQueue(reverseOrder)a = largest, then b = 2nd largest from the heapa ≠ b: push (a − b) back; if a == b: both destroyed, nothing pushed0We always need the two largest elements, and the heap gives us each in O(log n). With at most n rounds (each removes at least one stone), the total cost is O(n log n). A sorted array would need O(n) per round for insertion — the heap is the natural fit.
You could sort the stones again after every smash. That costs O(n log n) per turn, so O(n²) log n overall. We only ever need the two biggest values, which is exactly what a max heap gives us.
Put all stones into a max heap. A max heap is a binary tree stored in an array, where every parent is at least as big as its children. So the biggest stone always sits at the root. Poll twice to get the two heaviest stones. If they differ, push the difference back, and repeat while at least two stones remain.
When you repeatedly need the largest element, use a max heap. In Java, Collections dot reverse order turns a priority queue into a max heap.
Run the animation above on your own input, or watch the 2:03 video explanation of Last Stone Weight with a dry run and Java code.