思路分析
- 遍历每个小行星:
- 若栈为空 / 当前小行星向右(+)/ 栈顶小行星向左(-):无碰撞风险,直接入栈;
- 若当前小行星向左(-)且栈顶向右(+):触发碰撞,进入碰撞处理逻辑;
- 碰撞处理规则:
- 栈顶大小 < 当前小行星大小:栈顶爆炸(出栈),继续检查新栈顶;
- 栈顶大小 == 当前小行星大小:两者都爆炸(栈顶出栈,当前小行星丢弃);
- 栈顶大小 > 当前小行星大小:当前小行星爆炸(丢弃);
- 遍历结束后:栈中剩余元素即为碰撞后的结果。
代码实现
java
public int[] asteroidCollision(int[] asteroids) {
Stack<Integer> stack = new Stack<>();
for (int ast : asteroids) {
// 标记当前小行星是否存活(未爆炸)
boolean alive = true;
// 触发碰撞的条件:栈非空 + 当前小行星向左(-) + 栈顶向右(+)
while (alive && !stack.isEmpty() && ast < 0 && stack.peek() > 0) {
int top = stack.peek();
// 比较绝对值(大小)
if (Math.abs(ast) > Math.abs(top)) {
// 栈顶更小,爆炸(出栈),当前小行星继续检查新栈顶
stack.pop();
} else if (Math.abs(ast) == Math.abs(top)) {
// 大小相同,都爆炸
stack.pop();
alive = false; // 当前小行星标记为爆炸
} else {
// 当前小行星更小,爆炸
alive = false;
}
}
// 若当前小行星存活,入栈
if (alive) {
stack.push(ast);
}
}
// 将栈转换为结果数组
int[] res = new int[stack.size()];
for (int i = res.length - 1; i >= 0; i--) {
res[i] = stack.pop();
}
return res;
}