5858
5959<!-- 这里可写通用的实现逻辑 -->
6060
61- 可以类比成左右括号匹配:
61+ ** 方法一:栈 **
6262
63- - 向右移动的小行星(左括号):不会引发碰撞,直接入栈
64- - 向左移动的小行星(右括号):可能会和之前向右移动的小行星发生碰撞,特殊处理
63+ 我们从左到右遍历每个小行星 $x,ドル由于每个小行星可能与之前的多个小行星发生碰撞,考虑用栈来存储。
6564
66- 因为答案需要碰撞后剩下的所有小行星,相当于栈里最后剩下的元素,所以可以直接用数组表示栈
65+ - 对于当前小行星,如果 $x \gt 0,ドル那么它一定不会跟前面的小行星发生碰撞,我们可以直接将 $x$ 入栈。
66+ - 否则,如果栈不为空并且栈顶元素大于 0ドル,ドル且栈顶元素小于 $-x,ドル那么栈顶元素对应的小行星会发生爆炸,我们循环将栈顶元素出栈,直到不满足条件。此时如果栈顶元素等于 $-x,ドル那么两个小行星会发生爆炸,只需要将栈顶元素出栈即可;如果栈为空,或者栈顶元素小于 0ドル,ドル那么当前小行星不会发生碰撞,我们将 $x$ 入栈。
67+ 68+ 最后我们返回栈中的元素即为答案。
69+ 70+ 时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 是数组 $asteroids$ 的长度。
6771
6872<!-- tabs:start -->
6973
7478``` python
7579class Solution :
7680 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 )
8185 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
8993```
9094
9195### ** Java**
@@ -95,22 +99,22 @@ class Solution:
9599``` java
96100class Solution {
97101 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 );
102106 } 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();
105109 }
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 );
110114 }
111115 }
112116 }
113- return d . stream(). mapToInt(Integer :: valueOf). toArray();
117+ return stk . stream(). mapToInt(Integer :: valueOf). toArray();
114118 }
115119}
116120```
@@ -121,46 +125,94 @@ class Solution {
121125class Solution {
122126public:
123127 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 );
128132 } 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();
131135 }
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 );
136140 }
137141 }
138142 }
139- return ans ;
143+ return stk ;
140144 }
141145};
142146```
143147
144148### **Go**
145149
146150```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)
152155 } 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]
155158 }
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 )
160163 }
161164 }
162165 }
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+ }
164216}
165217```
166218
0 commit comments