Last Stone Weight
Description
We have a collection of stones, each stone has a positive integer weight.
Each turn, we choose the two heaviest stones and smash them together. Suppose the stones have weights x
and y
with x <= y
. The result of this smash is:
- If
x == y
, both stones are totally destroyed; - If
x != y
, the stone of weightx
is totally destroyed, and the stone of weighty
has new weighty-x
.
At the end, there is at most 1 stone left. Return the weight of this stone (or 0 if there are no stones left.)
Example 1:
Input: [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 last stone.
Note:
1 <= stones.length <= 30
1 <= stones[i] <= 1000
Solution(javascript)
class Heap {
constructor(list, compare = (a, b) => a - b) {
this.left = index => 2 * index + 1
this.right = index => 2 * index + 2
this.parent = index => Math.floor((index - 1) / 2)
this.heapify = (index = 0) => {
const { list } = this
const leftIndex = this.left(index)
const rightIndex = this.right(index)
let maxIndex = index
if (list[leftIndex] !== undefined
&& this.compare(list[maxIndex], list[leftIndex]) > 0) {
maxIndex = leftIndex
}
if (list[rightIndex] !== undefined
&& this.compare(list[maxIndex], list[rightIndex]) > 0) {
maxIndex = rightIndex
}
if (index !== maxIndex) {
const temp = list[index]
list[index] = list[maxIndex]
list[maxIndex] = temp
this.heapify(maxIndex)
}
}
this.buildHeap = () => {
for (let i = Math.floor(this.list.length / 2); i >= 0; i--) {
this.heapify(i)
}
return this.list
}
this.extract = () => {
const temp = this.list[0]
this.list[0] = this.list[this.list.length - 1]
this.list[this.list.length - 1] = temp
const result = this.list.pop()
this.heapify(0)
return result
}
this.insert = (item) => {
const { list } = this
list.push(item)
let index = list.length - 1
let parentIndex = this.parent(index)
while (list[parentIndex] !== undefined && this.compare(list[parentIndex], list[index]) > 0) {
const temp = list[index]
list[index] = list[parentIndex]
list[parentIndex] = temp
index = parentIndex
parentIndex = this.parent(index)
}
}
this.list = list
this.compare = compare
this.buildHeap()
}
}
const lastStoneWeight = (stones = []) => {
const maxHeap = new Heap(
stones,
(a, b) => b - a,
)
while (maxHeap.list.length >= 2) {
const num1 = maxHeap.extract()
const num2 = maxHeap.extract()
if (num1 !== num2) {
maxHeap.insert(num1 - num2)
}
}
return maxHeap.list.length === 0 ? 0 : maxHeap.list[0]
}