给定一个整数数组 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 。
示例 4:
输入:asteroids = [-2,-1,1,2] 输出:[-2,-1,1,2] 解释:-2 和 -1 向左移动,而 1 和 2 向右移动。 由于移动方向相同的行星不会发生碰撞,所以最终没有行星发生碰撞。
提示:
2 <= asteroids.length <= 104
-1000 <= asteroids[i] <= 1000
asteroids[i] != 0
注意:本题与主站 735 题相同: https://leetcode.cn/problems/asteroid-collision/
可以类比成左右括号匹配:
- 向右移动的小行星(左括号):不会引发碰撞,直接入栈
- 向左移动的小行星(右括号):可能会和之前向右移动的小行星发生碰撞,特殊处理
因为答案需要碰撞后剩下的所有小行星,相当于栈里最后剩下的元素,所以可以直接用数组表示栈
class Solution:
def asteroidCollision(self, asteroids: List[int]) -> List[int]:
ans = []
for a in asteroids:
if a > 0:
ans.append(a)
else:
while len(ans) > 0 and ans[-1] > 0 and ans[-1] < -a:
ans.pop()
if len(ans) > 0 and ans[-1] == -a:
ans.pop()
elif len(ans) == 0 or ans[-1] < -a:
ans.append(a)
return ans
class Solution {
public int[] asteroidCollision(int[] asteroids) {
Deque<Integer> d = new ArrayDeque<>();
for (int a : asteroids) {
if (a > 0) {
d.offerLast(a);
} else {
while (!d.isEmpty() && d.peekLast() > 0 && d.peekLast() < -a) {
d.pollLast();
}
if (!d.isEmpty() && d.peekLast() == -a) {
d.pollLast();
} else if (d.isEmpty() || d.peekLast() < -a) {
d.offerLast(a);
}
}
}
return d.stream().mapToInt(Integer::valueOf).toArray();
}
}
class Solution {
public:
vector<int> asteroidCollision(vector<int>& asteroids) {
vector<int> ans;
for (int a : asteroids) {
if (a > 0) {
ans.push_back(a);
} else {
while (!ans.empty() && ans.back() > 0 && ans.back() < -a) {
ans.pop_back();
}
if (!ans.empty() && ans.back() == -a) {
ans.pop_back();
} else if (ans.empty() || ans.back() < -a) {
ans.push_back(a);
}
}
}
return ans;
}
};
func asteroidCollision(asteroids []int) []int {
var ans []int
for _, a := range asteroids {
if a > 0 {
ans = append(ans, a)
} else {
for len(ans) > 0 && ans[len(ans)-1] > 0 && ans[len(ans)-1] < -a {
ans = ans[:len(ans)-1]
}
if len(ans) > 0 && ans[len(ans)-1] == -a {
ans = ans[:len(ans)-1]
} else if len(ans) == 0 || ans[len(ans)-1] < -a {
ans = append(ans, a)
}
}
}
return ans
}