Featured image of post LeetCode 75系列 - 735. 小行星碰撞

LeetCode 75系列 - 735. 小行星碰撞

题目描述

给定一个整数数组 asteroids,表示在同一行的小行星。数组中小行星的索引表示它们在空间中的相对位置。

对于数组中的每一个元素,其绝对值表示小行星的大小,正负表示小行星的移动方向(正表示向右移动,负表示向左移动)。每一颗小行星以相同的速度移动。

找出碰撞后剩下的所有小行星。碰撞规则:两个小行星相互碰撞,较小的小行星会爆炸。如果两颗小行星大小相同,则两颗小行星都会爆炸。两颗移动方向相同的小行星,永远不会发生碰撞。

示例 1:

1
2
3
输入:asteroids = [5,10,-5]
输出:[5,10]
解释:10 和 -5 碰撞后只剩下 10 。 5 和 10 永远不会发生碰撞。

示例 2:

1
2
3
输入:asteroids = [8,-8]
输出:[]
解释:8 和 -8 碰撞后,两者都发生爆炸。

示例 3:

1
2
3
输入:asteroids = [10,2,-5]
输出:[10]
解释:2 和 -5 发生碰撞后剩下 -5 。10 和 -5 发生碰撞后剩下 10 。

提示:

  • 2 <= asteroids.length <= 104
  • -1000 <= asteroids[i] <= 1000
  • asteroids[i] != 0

题解

  1. 碰撞条件 只有当:
    • 当前小行星向左(aster < 0
    • 栈顶小行星向右(st.back() > 0
    • 栈不为空时才会发生碰撞。
  2. 碰撞处理
    • 如果栈顶小行星的绝对值小于当前小行星(st.back() < -aster),栈顶小行星爆炸,当前小行星还活着(alive = true),继续和下一个栈顶比较。
    • 如果栈顶小行星的绝对值等于当前小行星(st.back() == -aster),两者都爆炸(alive = false),栈顶弹出。
    • 如果栈顶小行星的绝对值大于当前小行星(st.back() > -aster),当前小行星爆炸(alive = false),栈顶不变。
  3. 存活判断 如果当前小行星在碰撞后还活着(alive == true),就入栈。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
    vector<int> asteroidCollision(vector<int>& asteroids) {
         vector<int> st; // 保存当前还未爆炸的小行星
        for (auto aster : asteroids) {
            bool alive = true;
            while (alive && aster < 0 && !st.empty() && st.back() > 0) {
                alive = st.back() < -aster; // aster 是否存在
                if (st.back() <= -aster) {  // 栈顶行星爆炸
                    st.pop_back();
                }
            }
            if (alive) {
                st.push_back(aster);
            }
        }
        return st;
    }
};