ammar@web:~$
~/leetcode/easy/last-stone-weight
Easy·[2026-03-27]

1046. Last Stone Weight

[#heap]

## description

## 1046. Last Stone Weight

You are given an array of integers stones where stones[i] is the weight of the ith stone.

We are playing a game with the stones. On each turn, we choose the heaviest two stones and smash them together. Suppose the heaviest two stones have weights x and y with x <= y. The result of this smash is:

  • If x == y, both stones are destroyed, and
    • If x != y, the stone of weight x is destroyed, and the stone of weight y has new weight y - x.

      At the end of the game, there is at most one stone left.

      Return the weight of the last remaining stone. If there are no stones left, return 0.

      Example 1:

      plain text
      1Input: stones = [2,7,4,1,8,1] 2Output: 1 3Explanation: 4We combine 7 and 8 to get 1 so the array converts to [2,4,1,1,1] then, 5we combine 2 and 4 to get 2 so the array converts to [2,1,1,1] then, 6we combine 2 and 1 to get 1 so the array converts to [1,1,1] then, 7we combine 1 and 1 to get 0 so the array converts to [1] then that's the value of the last stone.

      Example 2:

      plain text
      1Input: stones = [1] 2Output: 1
      • 1 <= stones.length <= 30
        • 1 <= stones[i] <= 1000

          Constraints:

          ## notes

          ### Intuition

          We want to grab the two largest stones on every iteration.

          ### Implementation

          To efficiently grab the two largest stones on every iteration, we can use a max heap.

          Start by initializing our max heap. In Python, the standard heap is a min heap so we can negate each value to make it a max heap.

          Next, we iterate while the max heap has at least 2 elements:

          • Pop the two largest elements off the max heap, x and y (must be negated to get the actual values)
            • If x > y, swap them
              • If x == y, continue to the next iteration, no new stones added (both destroyed)
                • Otherwise, add y-x to the heap (must be negated to maintain max heap property)

                  When the iteration completes, we either have 1 or 0 elements in the max heap, return the element or 0 if its empty.

                  ### Edge-cases

                  Remember to negate when adding and negate when popping from the heap to ensure the max heap property is satisfied and we are comparing the actual stone values.

                  • Time: O(n log n), we iterate over all stones once and in each iteration we are popping from the heap which is O(log n).
                    • Space: O(n), the max heap will start with all elements.

                      ### Complexity

                      ## solution

                      python
                      1from typing import List 2import heapq 3 4class Solution: 5 def lastStoneWeight(self, stones: List[int]) -> int: 6 max_heap = [] 7 for stone in stones: 8 heapq.heappush(max_heap, -stone) 9 10 while len(max_heap) > 1: 11 x, y = -heapq.heappop(max_heap), -heapq.heappop(max_heap) 12 if x > y: 13 x, y = y, x 14 if x == y: 15 continue 16 else: 17 heapq.heappush(max_heap, -(y-x)) 18 19 return -max_heap[0] if max_heap else 0 20 21 22 23if __name__ == "__main__": 24 # Include one-off tests here or debugging logic that can be run by running this file 25 # e.g. print(solution.two_sum([1, 2, 3, 4], 3)) 26 solution = Solution() 27
                      --EOF--