Last Stone Weight — Solution in Python, Java & C++
Last Stone Weight solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. An easy problem on arrays and heap.
Last Stone Weight is an easy coding problem on arrays and heap.
- Difficulty: Easy
- Topics: Arrays, Heap
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
You have stones with weights stones[i]. Each turn, smash the two heaviest stones together: equal weights destroy both; otherwise the heavier survives with weight y - x.
Return the weight of the last remaining stone, or 0 if none remain.
Example 1
Input: stones = [2,7,4,1,8,1]
Output: 1
Explanation: 8&7→1, 4&2→2, 2&1→1, 1&1→0, leaving 1.
Example 2
Input: stones = [1]
Output: 1
Constraints
1 <= stones.length <= 301 <= stones[i] <= 100
Hints for Last Stone Weight
Hint 1
A max-heap gives you the two heaviest stones in O(log n).
Hint 2
Push back the difference when it's non-zero.
How to solve Last Stone Weight
The rules always ask for the two heaviest stones, and the smash puts a new stone back into the pile. That is exactly what a max-heap is for: it hands you the largest in O(log n) and absorbs the new stone just as cheaply. Simulate the process literally.
Approach
- Put every stone into a max-heap.
- While at least two stones remain, pop the two largest,
ythenx(soy >= x). - If they are equal, both are destroyed — push nothing back.
- Otherwise push
y - x, the surviving fragment. - When fewer than two stones remain, return the last one, or
0if the pile is empty.
Why it works
The process is fully determined — at every turn the pair to smash is forced — so a direct simulation cannot go wrong; the only question is how fast you can find the two heaviest. Each turn removes two stones and adds at most one, so the pile shrinks by at least one per turn and the loop always terminates in at most n rounds.
Complexity
- Time —
O(n log n) - Space —
O(n)
Pitfalls
- The pile can end up empty, not just with one stone — the answer is
0in that case, and indexing blindly will crash. - Push the difference back only when it is non-zero; pushing a
0stone corrupts later rounds. - Order matters when subtracting: it is
y - xwithythe larger, never the other way round.
Reference solution
Python
from typing import List
import heapq
def lastStoneWeight(stones: List[int]) -> int:
heap = [-s for s in stones]
heapq.heapify(heap)
while len(heap) > 1:
y = -heapq.heappop(heap)
x = -heapq.heappop(heap)
if y != x:
heapq.heappush(heap, -(y - x))
return -heap[0] if heap else 0Java
public static int lastStoneWeight(int[] stones) {
PriorityQueue<Integer> heap = new PriorityQueue<>(Collections.reverseOrder());
for (int s : stones) heap.add(s);
while (heap.size() > 1) {
int y = heap.poll();
int x = heap.poll();
if (y != x) heap.add(y - x);
}
return heap.isEmpty() ? 0 : heap.peek();
}C++
int lastStoneWeight(vector<int>& stones) {
priority_queue<int> heap(stones.begin(), stones.end());
while (heap.size() > 1) {
int y = heap.top();
heap.pop();
int x = heap.top();
heap.pop();
if (y != x) heap.push(y - x);
}
return heap.empty() ? 0 : heap.top();
}JavaScript
var lastStoneWeight = function(stones) {
const st = stones.slice();
while (st.length > 1) {
st.sort(function(a, b) { return a - b; });
const y = st.pop(), x = st.pop();
if (y !== x) st.push(y - x);
}
return st.length === 0 ? 0 : st[0];
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 1199 arrays problems · the whole catalogue
Learn the technique: Arrays · Heaps and Priority Queues