本文正在参加「Java主题月 – Java 刷题打卡」,详情查看<活动链接>
一、题目描述
行星碰撞
给定一个整数数组 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
二、思路分析
很明显这是一个比大小的问题,仍然使用栈来解决。
首先分析什么情况下行星会爆炸:
只有左边行星位正数,右边行星为负数才会爆炸。因此我们遇到正数就直接入栈,遇到负数则进行特殊处理:
- 如果栈空,直接入栈
- 如果栈中没有正数,直接入栈
- 如果正数大于当前行星,什么也不做
- 如果正数等于当前行星,直接把正数出栈
- 如果正数小于当前行星,正数出栈,当前行星入栈。
三、AC代码
public int[] asteroidCollision(int[] asteroids) {
Stack<Integer> stack = new Stack<>();
for (int i : asteroids) {
if (i > 0) {
stack.push(i);
} else {
while (!stack.isEmpty() && stack.peek() > 0 && stack.peek() < Math.abs(i)) {
stack.pop();
}
if (stack.isEmpty()) {
stack.push(i);
} else {
if (stack.peek() < 0) {
stack.push(i);
} else {
if (stack.peek() > Math.abs(i)) {
} else {
stack.pop();
}
}
}
}
}
int[] res = new int[stack.size()];
for (int i = 0; i < stack.size(); i++) {
res[stack.size()-i-1] = stack.pop();
}
return res;
}
复制代码
四、总结
其实这些栈相关的题目都比较类似。
首先对入参进行遍历,其次找好条件进行while
循环,直到取到最值。循环完答案就出来了。
其中难点是如何确定while
循环的条件,好好梳理思路,多加练习,就会越来越简单!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END