置頂

我的 VPython 教學文件 (HackMD 版本)

VPython 教學文件目錄 安裝及測試 基本語法 等速度直線運動 自由落下 終端速度 水平抛射 使用For迴圈計算水平抛射資料 斜向抛射 圓周運動 簡諧運動 單擺 木塊彈簧系統分離 重力及簡諧 行星運動 相疊木塊 雙重簡諧運動 一維彈性碰撞 ...

熱門文章

2026年9月18日 星期五

LeetCode 解題筆記:735. Asteroid Collision

作者:王一哲
日期:2026年9月18日


LeetCode 題目連結:735. Asteroid Collision

解題想法


中等難度題,題目給一個陣列 $asteroids$,索引值代表小行星的位置,數值的絕對值代表小行星的大小,正值代表小行星向右移動,負值代表小行星向左移動,每個小行星的速度量值都相等。如果兩個小行星碰撞,會留下較大的小行星;如果兩者一樣大,兩者一起撞掉。題目要求最後留下來的小行星資料。

這題可以用堆疊解題。先建一個 list 或 vector $st$。用 for 迴圈依序讀取小行星的大小及移動方向 $a$,如果 st 是空的、st 最後一項是負的或者st 最後一項是正的且 a 是正的,不會碰撞,直接加入 a;如果發生碰撞,再用一個 while 迴圈,檢查 $a$ 與 $st$ 最後一項的關係,再決定是否移除 $st$ 的最後一項,以及是否要將 $a$ 加入 $st$。詳細的過程請看程式碼及註解。

Python 程式碼


Runtime: 3 ms, beats 94.41%. Memory: 20.38 MB, beats 33.14%.
class Solution:
    def asteroidCollision(self, asteroids: List[int]) -> List[int]:
        st = []
        for a in asteroids:
            # 如果 st 是空的、st 最後一項是負的或者st 最後一項是正的且 a 是正的,不會碰撞,直接加入 a
            if not st or st[-1] < 0 or (st[-1] > 0 and a > 0):
                st.append(a)
            else:  # 發生碰撞
                add_new = True  # 是否加入 a
                # 如果 st 有資料、 st 最後一項是正的且 a 是負的,發生碰撞
                while st and st[-1] > 0 and a < 0:
                    # a 量值較大,st 最後一項被撞掉
                    if abs(a) > st[-1]:
                        st.pop()
                    # 一樣大,st 最後一項及 a 同時被撞掉
                    elif abs(a) == st[-1]:
                        st.pop()
                        add_new = False
                        break
                    # a 較小,a 被撞掉
                    else:
                        add_new = False
                        break
                # 加入 a
                if add_new: st.append(a)
        return st


C++ 程式碼


Runtime: 0 ms, beats 100.00%. Memory: 21.50 MB, beats 97.22%.
class Solution {
public:
    vector<int> asteroidCollision(vector<int>& asteroids) {
        vector<int> st;
        for(int a : asteroids) {
            // 如果 st 是空的、st 最後一項是負的或者st 最後一項是正的且 a 是正的,不會碰撞,直接加入 a
            if (st.empty() || st.back() < 0 || (st.back() > 0 && a > 0)) {
                st.push_back(a);
            } else {  // 發生碰撞
                bool add_new = true;  // 是否加入 a
                // 如果 st 有資料、 st 最後一項是正的且 a 是負的,發生碰撞
                while(!st.empty() && st.back() > 0 && a < 0) {
                    // a 量值較大,st 最後一項被撞掉
                    if (abs(a) > st.back()) {
                        st.pop_back();
                    } else if (abs(a) == st.back()) {
                        // 一樣大,st 最後一項及 a 同時被撞掉
                    
                        st.pop_back();
                        add_new = false;
                        break;
                    } else {  // a 較小,a 被撞掉
                        add_new = false;
                        break;
                    }
                }
                // 加入 a
                if (add_new) st.push_back(a);
            }
        }
        return st;
    }
};


沒有留言:

張貼留言