LeetCode 735.行星碰撞

题目描述

给定一个整数数组 a s t e r o i d s asteroids asteroids,表示在同一行的行星。

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

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 2 < = a s t e r o i d s . l e n g t h < = 1 0 4 2 <= asteroids.length <= 10^{4} 2<=asteroids.length<=104
  • − 1000 < = a s t e r o i d s [ i ] < = 1000 -1000 <= asteroids[i] <= 1000 1000<=asteroids[i]<=1000
  • a s t e r o i d s [ i ] ! = 0 asteroids[i] != 0 asteroids[i]!=0

思路

1.遍历输入数组,如果栈为空,直接将当前元素压入栈里。如果栈非空,则进行判断。
栈非空,则栈顶的元素和输入元素分别为两个行星。栈顶元素是左边的行星,输入元素是右边的行星。

2.判断两个行星的运动方向
如果两个行星同方向,或者左边的行星向左,右边的行星向右,两颗行星就不会发生碰撞,直接将右行星入栈。
如果不是以上的情况,两个行星一定会发生碰撞。

一定会发生碰撞的情况:
1.左边行星绝对值 > 右边行星绝对值
右行星爆炸,所以左行星不出栈,右行星不入栈,进入下一轮循环。
2.左边行星绝对值 == 右边行星绝对值
两个行星都爆炸,左行星出栈,右行星不入栈,进入下一轮循环。
3.左边行星绝对值 < 右边行星绝对值
左行星爆炸,所以左行星出栈,而右行星不可以入栈,还需要判断左边是否还有冲突的行星,所以需要再次进行判断。
代码中我使用了i–,进入新的循环,但执行了i–之后输入元素还是上一轮的元素,所以可以实现再次判断。

循环结束后所有元素出栈到返回数组中。

C++ 代码
class Solution {
public:
    vector<int> asteroidCollision(vector<int>& asteroids) {
        // 定义栈
        stack<int> s;
        // 返回数组
        vector<int> ret;

        // 遍历输入数组
        for (int i = 0; i < asteroids.size(); i++)
        {
            // 栈非空
            if (!s.empty())
            {
                // 栈顶元素和输入元素同方向 或者 栈顶元素向左输入元素向右 输入元素入栈
                if ((s.top() < 0 && asteroids[i] < 0) || (s.top() > 0 && asteroids[i] > 0) 
                || (s.top() < 0 && asteroids[i] > 0))
                    s.push(asteroids[i]);
                // 栈顶元素向右 输入元素向左 会产生碰撞
                else
                {
                    // a为栈顶元素绝对值 b为输入元素绝对值
                    int a = abs(s.top()), b = abs(asteroids[i]);

                    // a > b 栈顶元素绝对值更大 输入元素爆炸 进入下一轮循环
                    // a == b 栈顶元素和输入元素绝对值相等 两个元素都爆炸
                    // a < b 栈顶元素爆炸 输入元素继续循环判断
                    if (a > b) continue;
                    else if (a == b) { s.pop(); continue; }
                    else if (a < b) { s.pop(); i--; }
                }
            }
            // 栈为空就直接push入栈
            else s.push(asteroids[i]);
        }

        // 栈非空 存入返回数组
        while (!s.empty())
        {
            ret.push_back(s.top());
            s.pop();
        }
        // 返回数组倒序
        reverse(ret.begin(), ret.end());
        return ret;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值