LeetCode Note Java 01046:Last Stone Weight

情境題:砸石頭遊戲,每回合從石頭堆中取出兩顆最重的石頭互砸,石頭彼此會依重量相互抵消重量,即一樣重的石頭互砸就兩顆都會消失,不一樣重的石頭互砸,較重的石頭會扣掉較輕石頭的重量後生成新的石頭,將新石頭加入下回合的石頭堆。返回最後剩下的石頭重量,若沒有剩下石頭則返回 0。

題目

Last Stone Weight Easy

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.

解法

將容器排序後,每次移出兩個最大的石頭來破壞,破壞後如果有剩下小石頭要加回容器,一直循環到只剩一顆或沒石頭。

看起來最麻煩的是新產出的小石頭加進容器後需要排序這件事。

好在有特殊的資料結構可以自動做這件事 – PriorityQueue。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int lastStoneWeight(int[] stones) {
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder()); // 建造每次都會返回最大值的 PriorityQueue。
for (int i : stones) { // 還沒找到自動將 int[] 直接轉換成 PriorityQueue 的優雅方式,所以逐一將 int[] 的值加入 PriorityQueue。
pq.add(i);
}
while (pq.size() > 1) { // 容量大於一時不斷進行遊戲。
int a = pq.poll(); // 最重的石頭。
int b = pq.poll(); // 次重的石頭。
int c = a - b; // 兩石頭互砸後生成的新石頭重量。
if (c != 0) { // 如果有生成新石頭就要將新石頭加入 PriorityQueue。
pq.add(c);
}
}
return pq.size() > 0 ? pq.poll() : 0; // 若容器被清空就返回0,不然就返回最後一顆石頭的重量。
}
}

選對容器後,照著遊戲規則就能簡單寫出答案。

就是前提是要先學會使用該工具。