小行星碰撞
难度:
标签:
题目描述
代码结果
运行时间: 24 ms, 内存: 17.0 MB
/*
* 思路:
* 使用Stack存储行星。对于每个小行星,如果是负数且栈顶是正数,则表示可能发生碰撞。否则直接入栈。
* 使用Stream生成最终结果。
*/
import java.util.Stack;
import java.util.Arrays;
public class AsteroidCollisionStream {
public int[] asteroidCollision(int[] asteroids) {
Stack<Integer> stack = new Stack<>();
Arrays.stream(asteroids).forEach(asteroid -> {
boolean alive = true;
while (alive && !stack.isEmpty() && stack.peek() > 0 && asteroid < 0) {
int top = stack.pop();
if (top + asteroid == 0) {
alive = false; // both explode
} else if (top + asteroid > 0) {
asteroid = top; // top survives
} // else, asteroid survives (keep alive = true)
}
if (alive) stack.push(asteroid);
});
return stack.stream().mapToInt(i -> i).toArray();
}
}
解释
方法:
这个题解使用了栈的数据结构。遍历给定的小行星数组,对于每个小行星,根据其运动方向和栈顶小行星的情况进行处理。如果当前小行星向右运动(正数),直接将其压入栈中;如果向左运动(负数),则与栈顶的小行星进行比较。如果栈顶小行星向右运动且体积更大,则弹出栈顶小行星,继续比较,直到栈为空或者当前小行星体积更大。如果最终栈为空或者当前小行星存活,则将当前小行星压入栈中。遍历完整个数组后,栈中剩余的小行星即为碰撞后存活的小行星。
时间复杂度:
O(n^2),其中 n 是数组的长度,但平均情况下接近 O(n)。
空间复杂度:
O(n),其中 n 是数组的长度。
代码细节讲解
🦆
为什么选择使用栈结构来解决这个问题,栈有哪些特性使其适合处理小行星碰撞的场景?
▷🦆
如果小行星数组中所有元素都是负数,算法的行为会有什么不同?
▷🦆
解题思路中提到,如果栈顶小行星向右运动且体积更小,则栈顶小行星爆炸。这里为何不考虑当前向左运动的小行星也可能爆炸的情况?
▷🦆
在处理小行星碰撞的过程中,如果遇到栈顶小行星体积与当前小行星体积相等且相反方向的情况,为何选择直接将两者都爆炸而不保留任何一方?
▷相关问题
种花问题
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组 flowerbed
表示花坛,由若干 0
和 1
组成,其中 0
表示没种植花,1
表示种植了花。另有一个数 n
,能否在不打破种植规则的情况下种入 n
朵花?能则返回 true
,不能则返回 false
。
示例 1:
输入:flowerbed = [1,0,0,0,1], n = 1 输出:true
示例 2:
输入:flowerbed = [1,0,0,0,1], n = 2 输出:false
提示:
1 <= flowerbed.length <= 2 * 104
flowerbed[i]
为0
或1
flowerbed
中不存在相邻的两朵花0 <= n <= flowerbed.length