首先给出栈的几个基本操作
题目:
给定一个整数数组 asteroids,表示在同一行的小行星。
对于数组中的每一个元素,其绝对值表示小行星的大小,正负表示小行星的移动方向(正表示向右移动,负表示向左移动)。每一颗小行星以相同的速度移动。
找出碰撞后剩下的所有小行星。碰撞规则:两个行星相互碰撞,较小的行星会爆炸。如果两颗行星大小相同,则两颗行星都会爆炸。两颗移动方向相同的行星,永远不会发生碰撞。
数据范围:
2 <= asteroids.length <= 10 ^ 4
-1000 <= asteroids[i] <= 1000
asteroids[i] != 0
示例 1:
输入:asteroids = [5,10,-5]
输出:[5,10]
解释:10 和 -5 碰撞后只剩下 10 。 5 和 10 永远不会发生碰撞。
示例 2:
输入:asteroids = [8,-8]
输出:[]
解释:8 和 -8 碰撞后,两者都发生爆炸。
分析
何时入栈
1.栈为空时
2.栈顶元素为负数(下一个为负数则一起向左,下一个为正数则分向两边)
3.当前元素为正数(栈顶为正一起向右,栈顶为负分向两边)
接下来,我们需要看碰撞的场景又细分为什么情况:
1.栈顶元素大于当前元素,当前元素被撞毁
2.栈顶元素等于当前元素,栈顶弹出和当前元素抵消
3.栈顶元素小于当前元素,栈顶弹出,并与新栈顶完成上述判断
最终返回栈即可。
code
栈实现
class Solution {
public:
vector<int> asteroidCollision(vector<int>& asteroids) {
stack<int> s;
for (int i = 0; i < asteroids.size(); i++)
{
if (s.empty() || s.top() < 0 || s.top() * asteroids[i] > 0)
s.push(asteroids[i]);
else if (s.top() + asteroids[i] <= 0)
{
if (s.top() + asteroids[i] < 0) i--;
s.pop();
}
}
vector<int> res;
while (!s.empty())
{
res.push_back(s.top());
s.pop();
}
reverse(res.begin(), res.end());
return res;
}
};
用vector代替栈
class Solution {
public:
vector<int> asteroidCollision(vector<int>& asteroids) {
vector<int> s;
for (int i = 0; i < asteroids.size(); i ++ )
{
if (s.empty() || s.back() < 0 || s.back() * asteroids[i] > 0)
s.push_back(asteroids[i]);
else if (s.back() + asteroids[i] <= 0)
{
if (s.back() + asteroids[i] < 0) i -- ;
s.pop_back();
}
}
return s;
}
};