Problem
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 weightx
is destroyed, and the stone of weighty
has new weighty - 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:
Input: stones = [2,7,4,1,8,1] Output: 1 Explanation: We combine 7 and 8 to get 1 so the array converts to [2,4,1,1,1] then, we combine 2 and 4 to get 2 so the array converts to [2,1,1,1] then, we combine 2 and 1 to get 1 so the array converts to [1,1,1] then, we combine 1 and 1 to get 0 so the array converts to [1] then that's the value of the last stone.
Example 2:
Input: stones = [1] Output: 1
Intuition
The problem involves simulating the process of smashing stones together until there is at most one stone left. The simulation can be efficiently performed using a min-heap, where we repeatedly remove the two heaviest stones, perform the smashing operation, and insert the result back into the heap.
Approach
Initialization:
The array stones is negated to create a max-heap effect, as Python's heapq module provides a min-heap implementation.
The negated stones array is heapified using heapq.heapify to maintain the max-heap property.
Simulation:
While the number of stones in the heap is greater than 1:
The two heaviest stones are removed from the heap using heapq.heappop.
If the two stones have different weights, a new stone is created with weight abs(second - first) and inserted back into the heap using heapq.heappush.
Result:
After the simulation, there is at most one stone left in the heap.
If there is a stone left, its weight is returned as the result. Otherwise, 0 is returned.
Complexity
- Time complexity:
The time complexity is O(n log n), where n is the number of stones. Each heap operation (pop or push) takes O(log n) time, and the simulation involves n - 1 such operations.
- Space complexity:
The space complexity is O(n) for the heap.
Code
class Solution:
def lastStoneWeight(self, stones: List[int]) -> int:
stones = [-s for s in stones]
heapq.heapify(stones)
while len(stones) > 1:
first = heapq.heappop(stones)
second = heapq.heappop(stones)
if second > first:
heapq.heappush(stones, first - second)
stones.append(0)
return abs(stones[0])