1046. Last Stone Weight

練習日期:2026-03-29

難度:Easy

類型:Array、Heap (Priority Queue)

📘 題目敘述

給定一個整數陣列 stones,其中 stones[i] 表示第 i 顆石頭的重量。

現在要進行一個遊戲。每一回合都會選出目前最重的兩顆石頭互相撞擊。

假設這兩顆石頭的重量分別是 xy,且 x <= y,撞擊後會有兩種情況:

  • 如果 x == y,那這兩顆石頭都會被摧毀
  • 如果 x != y,那重量為 x 的石頭會被摧毀,而重量為 y 的石頭會變成新重量 y - x

最後最多只會剩下一顆石頭。

請回傳最後剩下那顆石頭的重量。

如果一顆都不剩,回傳 0

條件限制

  • 1 <= stones.length <= 30
  • 1 <= stones[i] <= 1000

🧠 解題思路

我這題的想法就是直接模擬題目過程,然後用 priority_queue 快速拿到目前最重的兩顆石頭。

因為每一回合都要找「最大的兩個」,這種操作很適合用 max heap。

在 C++ 裡,priority_queue<int> 預設就是最大堆,所以我可以把所有石頭先丟進去。

之後每次:

  • 先拿出最重的兩顆
  • 看它們相撞後會不會留下新石頭
  • 如果有,就把新石頭再丟回 heap

一直做到 heap 裡剩 0 顆或 1 顆石頭為止。

所有變數

  • pq:max heap,裡面放目前所有還存在的石頭重量
  • x:這一回合取出的其中一顆石頭重量
  • y:這一回合取出的另一顆石頭重量

🪜 主要流程步驟

1. 先把所有石頭放進 priority_queue

我先建立一個 priority_queue<int>,讓它幫我維護目前所有石頭中的最大值。

然後把 stones 裡的每顆石頭都放進去:

這樣之後每次都能直接從 pq.top() 拿到目前最重的石頭。


2. 每次取出最重的兩顆石頭來撞

只要 pq.size() > 1,就代表目前至少還有兩顆石頭可以互撞。

所以我在迴圈裡每次都做這件事:

  • 先取出第一顆最重的石頭 x
  • 再取出第二顆最重的石頭 y

因為 priority_queue 每次都會把目前最大的值放在頂端,所以這樣拿到的就是當前最重的兩顆石頭。


3. 如果兩顆一樣重,就直接消失

如果 x - y == 0,代表兩顆石頭重量一樣。

按照題目規則,這兩顆都會被摧毀,所以這回合不用再做其他事情,直接進下一輪就可以。

也就是這回合拿出來的兩顆石頭都不會再放回去。


4. 如果兩顆不一樣重,就把差值丟回去

如果兩顆石頭重量不同,那麼比較輕的那顆會消失,比較重的那顆則會變成它們重量差。

所以我就把:

abs(x - y)

再放回 pq

因為這顆新石頭之後還可能再和其他石頭互撞,所以要重新放回 heap 裡,讓後面的回合繼續使用。


5. 最後看 heap 裡還有沒有石頭

當迴圈結束時,只會有兩種情況:

  • pq 是空的,表示所有石頭都撞完消失了
  • pq 裡還剩一顆,表示那就是最後答案

所以最後我先判斷:

if (pq.empty()) {
    return 0;
}

如果是空的,就回傳 0

否則直接回傳 pq.top(),也就是最後剩下的那顆石頭重量。

⏱️ 複雜度

n = stones.length

  • 時間複雜度:O(n log n)
    一開始把石頭放進 heap,後面每回合都會做 pop 和 push,而 heap 操作是 O(log n)

  • 空間複雜度:O(n)
    priority_queue 需要存目前所有石頭。

💻 程式碼實作

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        priority_queue<int> pq;
        for (int i : stones) {
            pq.push(i);
        }
        while (pq.size() > 1) {
            int x = pq.top();
            pq.pop();
            int y = pq.top();
            pq.pop();
            if ((x - y) == 0) {
                continue;
            }
            pq.push(abs(x - y));
        }
        if (pq.empty()) {
            return 0;
        }
        return pq.top();
    }
};

https://leetcode.com/problems/last-stone-weight/

作者: scottnick
撰寫日期: 2026-03-29
類別:
原文連結: https://scottnick.github.io/cpp-notes/all%20problems/1046-last-stone-weight.html