Skip to content

Commit 4b378a0

Browse files
committed
feat: add solutions to lc problem: No.0305.Number of Islands II
1 parent 526b013 commit 4b378a0

File tree

6 files changed

+558
-4
lines changed

6 files changed

+558
-4
lines changed

solution/0300-0399/0305.Number of Islands II/README.md

Lines changed: 229 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,27 +63,254 @@
6363

6464
<p>你是否能在 O(k log mn) 的时间复杂度程度内完成每次的计算?(k 表示&nbsp;<code>positions</code>&nbsp;的长度)</p>
6565

66-
6766
## 解法
6867

6968
<!-- 这里可写通用的实现逻辑 -->
7069

70+
并查集。
71+
72+
并查集模板:
73+
74+
模板 1——朴素并查集:
75+
76+
```python
77+
# 初始化,p存储每个点的父节点
78+
p = list(range(n))
79+
80+
# 返回x的祖宗节点
81+
def find(x):
82+
if p[x] != x:
83+
# 路径压缩
84+
p[x] = find(p[x])
85+
return p[x]
86+
87+
# 合并a和b所在的两个集合
88+
p[find(a)] = find(b)
89+
```
90+
91+
模板 2——维护 size 的并查集:
92+
93+
```python
94+
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
95+
p = list(range(n))
96+
size = [1] * n
97+
98+
# 返回x的祖宗节点
99+
def find(x):
100+
if p[x] != x:
101+
# 路径压缩
102+
p[x] = find(p[x])
103+
return p[x]
104+
105+
# 合并a和b所在的两个集合
106+
if find(a) != find(b):
107+
size[find(b)] += size[find(a)]
108+
p[find(a)] = find(b)
109+
```
110+
111+
模板 3——维护到祖宗节点距离的并查集:
112+
113+
```python
114+
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
115+
p = list(range(n))
116+
d = [0] * n
117+
118+
# 返回x的祖宗节点
119+
def find(x):
120+
if p[x] != x:
121+
t = find(p[x])
122+
d[x] += d[p[x]]
123+
p[x] = t
124+
return p[x]
125+
126+
# 合并a和b所在的两个集合
127+
p[find(a)] = find(b)
128+
d[find(a)] = distance
129+
```
130+
71131
<!-- tabs:start -->
72132

73133
### **Python3**
74134

75135
<!-- 这里可写当前语言的特殊实现逻辑 -->
76136

77137
```python
78-
138+
class Solution:
139+
def numIslands2(self, m: int, n: int, positions: List[List[int]]) -> List[int]:
140+
p = list(range(m * n))
141+
grid = [[0] * n for _ in range(m)]
142+
143+
def check(i, j):
144+
return 0 <= i < m and 0 <= j < n and grid[i][j] == 1
145+
146+
def find(x):
147+
if p[x] != x:
148+
p[x] = find(p[x])
149+
return p[x]
150+
151+
res = []
152+
cur = 0
153+
for i, j in positions:
154+
if grid[i][j] == 1:
155+
res.append(cur)
156+
continue
157+
grid[i][j] = 1
158+
cur += 1
159+
for x, y in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
160+
if check(i + x, j + y) and find(i * n + j) != find((i + x) * n + j + y):
161+
p[find(i * n + j)] = find((i + x) * n + j + y)
162+
cur -= 1
163+
res.append(cur)
164+
return res
79165
```
80166

81167
### **Java**
82168

83169
<!-- 这里可写当前语言的特殊实现逻辑 -->
84170

85171
```java
172+
class Solution {
173+
private int[] p;
174+
private int[][] dirs = new int[][]{{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
175+
private int[][] grid;
176+
private int m;
177+
private int n;
178+
179+
public List<Integer> numIslands2(int m, int n, int[][] positions) {
180+
p = new int[m * n];
181+
for (int i = 0; i < p.length; ++i) {
182+
p[i] = i;
183+
}
184+
grid = new int[m][n];
185+
this.m = m;
186+
this.n = n;
187+
List<Integer> res = new ArrayList<>();
188+
int cur = 0;
189+
for (int[] position : positions) {
190+
int i = position[0], j = position[1];
191+
if (grid[i][j] == 1) {
192+
res.add(cur);
193+
continue;
194+
}
195+
grid[i][j] = 1;
196+
++cur;
197+
for (int[] e : dirs) {
198+
if (check(i + e[0], j + e[1]) && find(i * n + j) != find((i + e[0]) * n + j + e[1])) {
199+
p[find(i * n + j)] = find((i + e[0]) * n + j + e[1]);
200+
--cur;
201+
}
202+
}
203+
res.add(cur);
204+
}
205+
return res;
206+
}
207+
208+
private boolean check(int i, int j) {
209+
return i >= 0 && i < m && j >= 0 && j < n && grid[i][j] == 1;
210+
}
211+
212+
private int find(int x) {
213+
if (p[x] != x) {
214+
p[x] = find(p[x]);
215+
}
216+
return p[x];
217+
}
218+
}
219+
```
220+
221+
### **C++**
222+
223+
```cpp
224+
class Solution {
225+
public:
226+
vector<int> p;
227+
int dirs[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
228+
229+
vector<int> numIslands2(int m, int n, vector<vector<int>>& positions) {
230+
p.resize(m * n);
231+
for (int i = 0; i < p.size(); ++i) p[i] = i;
232+
vector<vector<int>> grid(m, vector<int>(n, 0));
233+
vector<int> res;
234+
int cur = 0;
235+
for (auto position : positions)
236+
{
237+
int i = position[0], j = position[1];
238+
if (grid[i][j] == 1)
239+
{
240+
res.push_back(cur);
241+
continue;
242+
}
243+
grid[i][j] = 1;
244+
++cur;
245+
for (auto e : dirs) {
246+
if (check(i + e[0], j + e[1], grid) && find(i * n + j) != find((i + e[0]) * n + j + e[1]))
247+
{
248+
p[find(i * n + j)] = find((i + e[0]) * n + j + e[1]);
249+
--cur;
250+
}
251+
}
252+
res.push_back(cur);
253+
}
254+
return res;
255+
}
256+
257+
bool check(int i, int j, vector<vector<int>>& grid) {
258+
return i >= 0 && i < grid.size() && j >= 0 && j < grid[0].size() && grid[i][j] == 1;
259+
}
260+
261+
int find(int x) {
262+
if (p[x] != x) p[x] = find(p[x]);
263+
return p[x];
264+
}
265+
};
266+
```
86267

268+
### **Go**
269+
270+
```go
271+
var p []int
272+
273+
func numIslands2(m int, n int, positions [][]int) []int {
274+
p = make([]int, m*n)
275+
for i := 0; i < len(p); i++ {
276+
p[i] = i
277+
}
278+
grid := make([][]int, m)
279+
for i := 0; i < m; i++ {
280+
grid[i] = make([]int, n)
281+
}
282+
var res []int
283+
cur := 0
284+
dirs := [4][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}}
285+
for _, position := range positions {
286+
i, j := position[0], position[1]
287+
if grid[i][j] == 1 {
288+
res = append(res, cur)
289+
continue
290+
}
291+
grid[i][j] = 1
292+
cur++
293+
for _, e := range dirs {
294+
if check(i+e[0], j+e[1], grid) && find(i*n+j) != find((i+e[0])*n+j+e[1]) {
295+
p[find(i*n+j)] = find((i+e[0])*n + j + e[1])
296+
cur--
297+
}
298+
}
299+
res = append(res, cur)
300+
}
301+
return res
302+
}
303+
304+
func check(i, j int, grid [][]int) bool {
305+
return i >= 0 && i < len(grid) && j >= 0 && j < len(grid[0]) && grid[i][j] == 1
306+
}
307+
308+
func find(x int) int {
309+
if p[x] != x {
310+
p[x] = find(p[x])
311+
}
312+
return p[x]
313+
}
87314
```
88315

89316
### **...**

0 commit comments

Comments
 (0)