58
58
59
59
<!-- 这里可写通用的实现逻辑 -->
60
60
61
- 可以类比成左右括号匹配:
61
+ ** 方法一:栈 **
62
62
63
- - 向右移动的小行星(左括号):不会引发碰撞,直接入栈
64
- - 向左移动的小行星(右括号):可能会和之前向右移动的小行星发生碰撞,特殊处理
63
+ 我们从左到右遍历每个小行星 $x$,由于每个小行星可能与之前的多个小行星发生碰撞,考虑用栈来存储。
65
64
66
- 因为答案需要碰撞后剩下的所有小行星,相当于栈里最后剩下的元素,所以可以直接用数组表示栈
65
+ - 对于当前小行星,如果 $x \gt 0$,那么它一定不会跟前面的小行星发生碰撞,我们可以直接将 $x$ 入栈。
66
+ - 否则,如果栈不为空并且栈顶元素大于 $0$,且栈顶元素小于 $-x$,那么栈顶元素对应的小行星会发生爆炸,我们循环将栈顶元素出栈,直到不满足条件。此时如果栈顶元素等于 $-x$,那么两个小行星会发生爆炸,只需要将栈顶元素出栈即可;如果栈为空,或者栈顶元素小于 $0$,那么当前小行星不会发生碰撞,我们将 $x$ 入栈。
67
+
68
+ 最后我们返回栈中的元素即为答案。
69
+
70
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $asteroids$ 的长度。
67
71
68
72
<!-- tabs:start -->
69
73
74
78
``` python
75
79
class Solution :
76
80
def asteroidCollision (self , asteroids : List[int ]) -> List[int ]:
77
- ans = []
78
- for a in asteroids:
79
- if a > 0 :
80
- ans .append(a )
81
+ stk = []
82
+ for x in asteroids:
83
+ if x > 0 :
84
+ stk .append(x )
81
85
else :
82
- while len (ans) > 0 and ans [- 1 ] > 0 and ans [- 1 ] < - a :
83
- ans .pop()
84
- if len (ans) > 0 and ans [- 1 ] == - a :
85
- ans .pop()
86
- elif len (ans) == 0 or ans [- 1 ] < - a :
87
- ans .append(a )
88
- return ans
86
+ while stk and stk [- 1 ] > 0 and stk [- 1 ] < - x :
87
+ stk .pop()
88
+ if stk and stk [- 1 ] == - x :
89
+ stk .pop()
90
+ elif not stk or stk [- 1 ] < 0 :
91
+ stk .append(x )
92
+ return stk
89
93
```
90
94
91
95
### ** Java**
@@ -95,22 +99,22 @@ class Solution:
95
99
``` java
96
100
class Solution {
97
101
public int [] asteroidCollision (int [] asteroids ) {
98
- Deque<Integer > d = new ArrayDeque<> ();
99
- for (int a : asteroids) {
100
- if (a > 0 ) {
101
- d . offerLast(a );
102
+ Deque<Integer > stk = new ArrayDeque<> ();
103
+ for (int x : asteroids) {
104
+ if (x > 0 ) {
105
+ stk . offerLast(x );
102
106
} else {
103
- while (! d . isEmpty() && d . peekLast() > 0 && d . peekLast() < - a ) {
104
- d . pollLast();
107
+ while (! stk . isEmpty() && stk . peekLast() > 0 && stk . peekLast() < - x ) {
108
+ stk . pollLast();
105
109
}
106
- if (! d . isEmpty() && d . peekLast() == - a ) {
107
- d . pollLast();
108
- } else if (d . isEmpty() || d . peekLast() < - a ) {
109
- d . offerLast(a );
110
+ if (! stk . isEmpty() && stk . peekLast() == - x ) {
111
+ stk . pollLast();
112
+ } else if (stk . isEmpty() || stk . peekLast() < 0 ) {
113
+ stk . offerLast(x );
110
114
}
111
115
}
112
116
}
113
- return d . stream(). mapToInt(Integer :: valueOf). toArray();
117
+ return stk . stream(). mapToInt(Integer :: valueOf). toArray();
114
118
}
115
119
}
116
120
```
@@ -121,46 +125,94 @@ class Solution {
121
125
class Solution {
122
126
public:
123
127
vector<int > asteroidCollision(vector<int >& asteroids) {
124
- vector<int > ans ;
125
- for (int a : asteroids) {
126
- if (a > 0) {
127
- ans .push_back(a );
128
+ vector<int > stk ;
129
+ for (int x : asteroids) {
130
+ if (x > 0) {
131
+ stk .push_back(x );
128
132
} else {
129
- while (!ans.empty () && ans .back() > 0 && ans .back() < -a ) {
130
- ans .pop_back();
133
+ while (stk.size () && stk .back() > 0 && stk .back() < -x ) {
134
+ stk .pop_back();
131
135
}
132
- if (!ans.empty () && ans .back() == -a ) {
133
- ans .pop_back();
134
- } else if (ans .empty() || ans .back() < -a ) {
135
- ans .push_back(a );
136
+ if (stk.size () && stk .back() == -x ) {
137
+ stk .pop_back();
138
+ } else if (stk .empty() || stk .back() < 0 ) {
139
+ stk .push_back(x );
136
140
}
137
141
}
138
142
}
139
- return ans ;
143
+ return stk ;
140
144
}
141
145
};
142
146
```
143
147
144
148
### **Go**
145
149
146
150
```go
147
- func asteroidCollision(asteroids []int) []int {
148
- var ans []int
149
- for _, a := range asteroids {
150
- if a > 0 {
151
- ans = append(ans, a)
151
+ func asteroidCollision(asteroids []int) (stk []int) {
152
+ for _, x := range asteroids {
153
+ if x > 0 {
154
+ stk = append(stk, x)
152
155
} else {
153
- for len(ans ) > 0 && ans [len(ans )-1] > 0 && ans [len(ans )-1] < -a {
154
- ans = ans [:len(ans )-1]
156
+ for len(stk ) > 0 && stk [len(stk )-1] > 0 && stk [len(stk )-1] < -x {
157
+ stk = stk [:len(stk )-1]
155
158
}
156
- if len(ans ) > 0 && ans [len(ans )-1] == -a {
157
- ans = ans [:len(ans )-1]
158
- } else if len(ans ) == 0 || ans [len(ans )-1] < -a {
159
- ans = append(ans, a )
159
+ if len(stk ) > 0 && stk [len(stk )-1] == -x {
160
+ stk = stk [:len(stk )-1]
161
+ } else if len(stk ) == 0 || stk [len(stk )-1] < 0 {
162
+ stk = append(stk, x )
160
163
}
161
164
}
162
165
}
163
- return ans
166
+ return
167
+ }
168
+ ```
169
+
170
+ ### ** TypeScript**
171
+
172
+ ``` ts
173
+ function asteroidCollision(asteroids : number []): number [] {
174
+ const stk: number [] = [];
175
+ for (const x of asteroids ) {
176
+ if (x > 0 ) {
177
+ stk .push (x );
178
+ } else {
179
+ while (stk .length && stk .at (- 1 ) > 0 && stk .at (- 1 ) < - x ) {
180
+ stk .pop ();
181
+ }
182
+ if (stk .length && stk .at (- 1 ) === - x ) {
183
+ stk .pop ();
184
+ } else if (! stk .length || stk .at (- 1 ) < 0 ) {
185
+ stk .push (x );
186
+ }
187
+ }
188
+ }
189
+ return stk ;
190
+ }
191
+ ```
192
+
193
+ ### ** Rust**
194
+
195
+ ``` rust
196
+ impl Solution {
197
+ #[allow(dead_code)]
198
+ pub fn asteroid_collision (asteroids : Vec <i32 >) -> Vec <i32 > {
199
+ let mut stk = Vec :: new ();
200
+ for & x in & asteroids {
201
+ if x > 0 {
202
+ stk . push (x );
203
+ } else {
204
+ while ! stk . is_empty () && * stk . last (). unwrap () > 0 && * stk . last (). unwrap () < - x {
205
+ stk . pop ();
206
+ }
207
+ if ! stk . is_empty () && * stk . last (). unwrap () == - x {
208
+ stk . pop ();
209
+ } else if stk . is_empty () || * stk . last (). unwrap () < 0 {
210
+ stk . push (x );
211
+ }
212
+ }
213
+ }
214
+ stk
215
+ }
164
216
}
165
217
```
166
218
0 commit comments