Maintain a max heap so each round can remove the two largest stones and restore their positive difference.
Complexity
O(n log n) time and O(n) heap space.
Repeatedly smash the two heaviest stones and return the remaining weight.
Maintain a max heap so each round can remove the two largest stones and restore their positive difference.
O(n log n) time and O(n) heap space.
package main
import "container/heap"
type maxHeap []int
func (values maxHeap) Len() int { return len(values) }
func (values maxHeap) Less(i int, j int) bool { return values[i] > values[j] }
func (values maxHeap) Swap(i int, j int) { values[i], values[j] = values[j], values[i] }
func (values *maxHeap) Push(value any) { *values = append(*values, value.(int)) }
func (values *maxHeap) Pop() any {
old := *values
last := old[len(old)-1]
*values = old[:len(old)-1]
return last
}
func lastStoneWeight(stones []int) int {
stonesHeap := maxHeap(stones)
heap.Init(&stonesHeap)
for stonesHeap.Len() > 1 {
first := heap.Pop(&stonesHeap).(int)
second := heap.Pop(&stonesHeap).(int)
if first != second {
heap.Push(&stonesHeap, first-second)
}
}
if stonesHeap.Len() == 0 {
return 0
}
return heap.Pop(&stonesHeap).(int)
}
import heapq
class Solution:
def lastStoneWeight(self, stones: list[int]) -> int:
heap = [-stone for stone in stones]; heapq.heapify(heap)
while len(heap) > 1:
first, second = -heapq.heappop(heap), -heapq.heappop(heap)
if first != second: heapq.heappush(heap, second - first)
return -heap[0] if heap else 0
function lastStoneWeight(stones: number[]): number {
const heap: number[] = [];
const push = (value: number): void => { heap.push(value); let index = heap.length - 1; while (index > 0) { const parent = Math.floor((index - 1) / 2); if (heap[parent] >= heap[index]) break; [heap[parent], heap[index]] = [heap[index], heap[parent]]; index = parent; } };
const pop = (): number => { const root = heap[0]; const last = heap.pop(); if (heap.length && last !== undefined) { heap[0] = last; let index = 0; while (true) { const left = index * 2 + 1; const right = left + 1; let largest = index; if (left < heap.length && heap[left] > heap[largest]) largest = left; if (right < heap.length && heap[right] > heap[largest]) largest = right; if (largest === index) break; [heap[index], heap[largest]] = [heap[largest], heap[index]]; index = largest; } } return root; };
for (const stone of stones) push(stone);
while (heap.length > 1) { const first = pop(); const second = pop(); if (first !== second) push(first - second); }
return heap[0] ?? 0;
}