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
The problem statement itself states that at each iteration we need to pick out the max two elements. So we need some sort of sorting to always get the max two elements.
We can use the heap data structure to maintain a sorted state of elements and always pick out the max two. The algorithm would be like this.
- Add all the elements of the array to the max heap.
- Loop until heap size is greater than equal to two
- Take out the max two elements x, y;
- if they are not equal, insert x – y back into the heap.
- return 0 if the heap is empty, else return the top element of the heap.
The time complexity is O(n log n) and space complexity is O(n) where n is the size of the array.
class Solution {
public int lastStoneWeight(int[] stones) {
//Initialize Priority Queue to Max Heap
PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
//add all elements of stones array to priority queue
for(int stone: stones){
pq.add(stone);
}
//Loop until the heap has atleast two elements.
while(pq.size() >= 2){
//Pop out the two max elements
int x = pq.poll();
int y = pq.poll();
//Push the difference between the two values back into the queue
if(x != y){
pq.add(x - y);
}
}
// return 0 is queue is empty, else the top element
return pq.isEmpty() ? 0 : pq.poll();
}
}
Source – LeetCode
Code – LastStoneWeight.java