1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public int[] asteroidCollision(int[] asteroids) {
Deque<Integer> rightMovingRocks = new ArrayDeque<>();
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < asteroids.length; i++) {
if (asteroids[i] >= 0) {
rightMovingRocks.addLast(asteroids[i]);
} else {
while (!rightMovingRocks.isEmpty() && rightMovingRocks.peekLast() < Math.abs(asteroids[i])) {
rightMovingRocks.pollLast();
}
if (rightMovingRocks.isEmpty()) {
ans.add(asteroids[i]);
} else if (rightMovingRocks.peekLast() == Math.abs(asteroids[i])) {
rightMovingRocks.pollLast();
}
}
}
while (!rightMovingRocks.isEmpty()) {
ans.add(rightMovingRocks.pollFirst());
}
int[] result = new int[ans.size()];
for (int i = 0; i < result.length; i++) {
result[i] = ans.get(i);
}
return result;
}
}

就是从左往右遍历. 把往右边移动的asteroid存到栈中, 遇到往左移动的, 看能把栈中的asteroid抵消多少个. 如果都能抵消还存在, 那么这个往左移动就添加到最后的结果里面. 如果抵消不完或者抵消完最后一个自己也毁灭了, 那就继续. 最后把栈里剩下的添加到结果的后边即可. 因为栈出来是倒着出来的, 我们想要最底的先出, 于是我用了ArrayDeque.

时间复杂度: O(n) 因为正的元素最多经历进栈出栈, 负的元素只是可能被添加到ans中, 因此不会超过O(2n).
空间复杂度: O(n) 可能全部是正的.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public int[] asteroidCollision(int[] asteroids) {
Stack<Integer> survived = new Stack<>();
for (int asteroid : asteroids) {
if (asteroid > 0) {
survived.push(asteroid);
continue;
}
while (!survived.isEmpty() && survived.peek() > 0 && survived.peek() < Math.abs(asteroid)) {
survived.pop();
}
if (survived.isEmpty() || survived.peek() < 0) {
survived.push(asteroid);
} else if (survived.peek() == Math.abs(asteroid)) {
survived.pop();
}
}
int[] ans = new int[survived.size()];
for (int i = ans.length - 1; i >= 0; i--) {
ans[i] = survived.pop();
}
return ans;
}
}

这个是正负asteroid都往栈里面压. 只是里面的各种条件想了半天. 先分类asteroid是正还是负. 正的直接压入, 负的话继续判断. 当栈里有东西, 并且栈顶是正asteroid, 且它的值比当前的asteroid要小, 我们就把栈顶的pop出来. 一直重复. 结束循环后, 如果栈里没东西了, 或者栈里只剩下负的asteroid了, 那么把现在的asteroid压入栈. 如果不是那么只剩下栈顶是正的且大于等于现在的asteroid. 如果相等要把栈顶的pop出去, 不想等直接什么也不干就ok了.

时间复杂度: O(n)
空间复杂度: O(n)