Skip to content

Commit a40291f

Browse files
authoredSep 19, 2023
feat: add solutions to lc/lcof2 problems (#1647)
1 parent 6279a4b commit a40291f

File tree

15 files changed

+481
-469
lines changed

15 files changed

+481
-469
lines changed
 

‎lcof2/剑指 Offer II 037. 小行星碰撞/README.md

+101-49
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,16 @@
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

@@ -74,18 +78,18 @@
7478
```python
7579
class 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
96100
class 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 {
121125
class Solution {
122126
public:
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

Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
class Solution {
2-
public:
3-
vector<int> asteroidCollision(vector<int>& asteroids) {
4-
vector<int> ans;
5-
for (int a : asteroids) {
6-
if (a > 0) {
7-
ans.push_back(a);
8-
} else {
9-
while (!ans.empty() && ans.back() > 0 && ans.back() < -a) {
10-
ans.pop_back();
11-
}
12-
if (!ans.empty() && ans.back() == -a) {
13-
ans.pop_back();
14-
} else if (ans.empty() || ans.back() < -a) {
15-
ans.push_back(a);
16-
}
17-
}
18-
}
19-
return ans;
20-
}
21-
};
1+
class Solution {
2+
public:
3+
vector<int> asteroidCollision(vector<int>& asteroids) {
4+
vector<int> stk;
5+
for (int x : asteroids) {
6+
if (x > 0) {
7+
stk.push_back(x);
8+
} else {
9+
while (stk.size() && stk.back() > 0 && stk.back() < -x) {
10+
stk.pop_back();
11+
}
12+
if (stk.size() && stk.back() == -x) {
13+
stk.pop_back();
14+
} else if (stk.empty() || stk.back() < 0) {
15+
stk.push_back(x);
16+
}
17+
}
18+
}
19+
return stk;
20+
}
21+
};
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
func asteroidCollision(asteroids []int) []int {
2-
var ans []int
3-
for _, a := range asteroids {
4-
if a > 0 {
5-
ans = append(ans, a)
1+
func asteroidCollision(asteroids []int) (stk []int) {
2+
for _, x := range asteroids {
3+
if x > 0 {
4+
stk = append(stk, x)
65
} else {
7-
for len(ans) > 0 && ans[len(ans)-1] > 0 && ans[len(ans)-1] < -a {
8-
ans = ans[:len(ans)-1]
6+
for len(stk) > 0 && stk[len(stk)-1] > 0 && stk[len(stk)-1] < -x {
7+
stk = stk[:len(stk)-1]
98
}
10-
if len(ans) > 0 && ans[len(ans)-1] == -a {
11-
ans = ans[:len(ans)-1]
12-
} else if len(ans) == 0 || ans[len(ans)-1] < -a {
13-
ans = append(ans, a)
9+
if len(stk) > 0 && stk[len(stk)-1] == -x {
10+
stk = stk[:len(stk)-1]
11+
} else if len(stk) == 0 || stk[len(stk)-1] < 0 {
12+
stk = append(stk, x)
1413
}
1514
}
1615
}
17-
return ans
16+
return
1817
}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
class Solution {
2-
public int[] asteroidCollision(int[] asteroids) {
3-
Deque<Integer> d = new ArrayDeque<>();
4-
for (int a : asteroids) {
5-
if (a > 0) {
6-
d.offerLast(a);
7-
} else {
8-
while (!d.isEmpty() && d.peekLast() > 0 && d.peekLast() < -a) {
9-
d.pollLast();
10-
}
11-
if (!d.isEmpty() && d.peekLast() == -a) {
12-
d.pollLast();
13-
} else if (d.isEmpty() || d.peekLast() < -a) {
14-
d.offerLast(a);
15-
}
16-
}
17-
}
18-
return d.stream().mapToInt(Integer::valueOf).toArray();
19-
}
20-
}
1+
class Solution {
2+
public int[] asteroidCollision(int[] asteroids) {
3+
Deque<Integer> stk = new ArrayDeque<>();
4+
for (int x : asteroids) {
5+
if (x > 0) {
6+
stk.offerLast(x);
7+
} else {
8+
while (!stk.isEmpty() && stk.peekLast() > 0 && stk.peekLast() < -x) {
9+
stk.pollLast();
10+
}
11+
if (!stk.isEmpty() && stk.peekLast() == -x) {
12+
stk.pollLast();
13+
} else if (stk.isEmpty() || stk.peekLast() < 0) {
14+
stk.offerLast(x);
15+
}
16+
}
17+
}
18+
return stk.stream().mapToInt(Integer::valueOf).toArray();
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
class Solution:
2-
def asteroidCollision(self, asteroids: List[int]) -> List[int]:
3-
ans = []
4-
for a in asteroids:
5-
if a > 0:
6-
ans.append(a)
7-
else:
8-
while len(ans) > 0 and ans[-1] > 0 and ans[-1] < -a:
9-
ans.pop()
10-
if len(ans) > 0 and ans[-1] == -a:
11-
ans.pop()
12-
elif len(ans) == 0 or ans[-1] < -a:
13-
ans.append(a)
14-
return ans
1+
class Solution:
2+
def asteroidCollision(self, asteroids: List[int]) -> List[int]:
3+
stk = []
4+
for x in asteroids:
5+
if x > 0:
6+
stk.append(x)
7+
else:
8+
while stk and stk[-1] > 0 and stk[-1] < -x:
9+
stk.pop()
10+
if stk and stk[-1] == -x:
11+
stk.pop()
12+
elif not stk or stk[-1] < 0:
13+
stk.append(x)
14+
return stk
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
impl Solution {
2+
#[allow(dead_code)]
3+
pub fn asteroid_collision(asteroids: Vec<i32>) -> Vec<i32> {
4+
let mut stk = Vec::new();
5+
for &x in &asteroids {
6+
if x > 0 {
7+
stk.push(x);
8+
} else {
9+
while !stk.is_empty() && *stk.last().unwrap() > 0 && *stk.last().unwrap() < -x {
10+
stk.pop();
11+
}
12+
if !stk.is_empty() && *stk.last().unwrap() == -x {
13+
stk.pop();
14+
} else if stk.is_empty() || *stk.last().unwrap() < 0 {
15+
stk.push(x);
16+
}
17+
}
18+
}
19+
stk
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function asteroidCollision(asteroids: number[]): number[] {
2+
const stk: number[] = [];
3+
for (const x of asteroids) {
4+
if (x > 0) {
5+
stk.push(x);
6+
} else {
7+
while (stk.length && stk.at(-1) > 0 && stk.at(-1) < -x) {
8+
stk.pop();
9+
}
10+
if (stk.length && stk.at(-1) === -x) {
11+
stk.pop();
12+
} else if (!stk.length || stk.at(-1) < 0) {
13+
stk.push(x);
14+
}
15+
}
16+
}
17+
return stk;
18+
}

0 commit comments

Comments
 (0)