Skip to content

Commit 87166a2

Browse files
committed
feat: add solutions to lcci problem: No.16.19.Pond Sizes
1 parent fbc7213 commit 87166a2

File tree

6 files changed

+748
-0
lines changed

6 files changed

+748
-0
lines changed

lcci/16.19.Pond Sizes/README.md

+292
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,314 @@
2626

2727
<!-- 这里可写通用的实现逻辑 -->
2828

29+
并查集。
30+
31+
并查集模板:
32+
33+
模板 1——朴素并查集:
34+
35+
```python
36+
# 初始化,p存储每个点的父节点
37+
p = list(range(n))
38+
39+
# 返回x的祖宗节点
40+
def find(x):
41+
if p[x] != x:
42+
# 路径压缩
43+
p[x] = find(p[x])
44+
return p[x]
45+
46+
# 合并a和b所在的两个集合
47+
p[find(a)] = find(b)
48+
```
49+
50+
模板 2——维护 size 的并查集:
51+
52+
```python
53+
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
54+
p = list(range(n))
55+
size = [1] * n
56+
57+
# 返回x的祖宗节点
58+
def find(x):
59+
if p[x] != x:
60+
# 路径压缩
61+
p[x] = find(p[x])
62+
return p[x]
63+
64+
# 合并a和b所在的两个集合
65+
if find(a) != find(b):
66+
size[find(b)] += size[find(a)]
67+
p[find(a)] = find(b)
68+
```
69+
70+
模板 3——维护到祖宗节点距离的并查集:
71+
72+
```python
73+
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
74+
p = list(range(n))
75+
d = [0] * n
76+
77+
# 返回x的祖宗节点
78+
def find(x):
79+
if p[x] != x:
80+
t = find(p[x])
81+
d[x] += d[p[x]]
82+
p[x] = t
83+
return p[x]
84+
85+
# 合并a和b所在的两个集合
86+
p[find(a)] = find(b)
87+
d[find(a)] = distance
88+
```
89+
2990
<!-- tabs:start -->
3091

3192
### **Python3**
3293

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

3596
```python
97+
class Solution:
98+
def pondSizes(self, land: List[List[int]]) -> List[int]:
99+
m, n = len(land), len(land[0])
100+
p = list(range(m * n))
101+
size = [1] * (m * n)
102+
103+
def find(x):
104+
if p[x] != x:
105+
p[x] = find(p[x])
106+
return p[x]
107+
108+
def union(a, b):
109+
pa, pb = find(a), find(b)
110+
if pa == pb:
111+
return
112+
size[pb] += size[pa]
113+
p[pa] = pb
36114

115+
for i in range(m):
116+
for j in range(n):
117+
if land[i][j] != 0:
118+
continue
119+
idx = i * n + j
120+
if i < m - 1 and land[i + 1][j] == 0:
121+
union(idx, (i + 1) * n + j)
122+
if j < n - 1 and land[i][j + 1] == 0:
123+
union(idx, i * n + j + 1)
124+
if i < m - 1 and j < n - 1 and land[i + 1][j + 1] == 0:
125+
union(idx, (i + 1) * n + j + 1)
126+
if i < m - 1 and j > 0 and land[i + 1][j - 1] == 0:
127+
union(idx, (i + 1) * n + j - 1)
128+
129+
s = set()
130+
res = []
131+
for i in range(m * n):
132+
if land[i // n][i % n] != 0:
133+
continue
134+
root = find(i)
135+
if root not in s:
136+
s.add(root)
137+
res.append(size[root])
138+
res.sort()
139+
return res
37140
```
38141

39142
### **Java**
40143

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

43146
```java
147+
class Solution {
148+
private int[] p;
149+
private int[] size;
150+
151+
public int[] pondSizes(int[][] land) {
152+
int m = land.length, n = land[0].length;
153+
p = new int[m * n];
154+
size = new int[m * n];
155+
for (int i = 0; i < p.length; ++i) {
156+
p[i] = i;
157+
size[i] = 1;
158+
}
159+
for (int i = 0; i < m; ++i) {
160+
for (int j = 0; j < n; ++j) {
161+
if (land[i][j] != 0) {
162+
continue;
163+
}
164+
int idx = i * n + j;
165+
if (i < m - 1 && land[i + 1][j] == 0) {
166+
union(idx, (i + 1) * n + j);
167+
}
168+
if (j < n - 1 && land[i][j + 1] == 0) {
169+
union(idx, i * n + j + 1);
170+
}
171+
if (i < m - 1 && j < n - 1 && land[i + 1][j + 1] == 0) {
172+
union(idx, (i + 1) * n + j + 1);
173+
}
174+
if (i < m - 1 && j > 0 && land[i + 1][j - 1] == 0) {
175+
union(idx, (i + 1) * n + j - 1);
176+
}
177+
}
178+
}
179+
Set<Integer> s = new HashSet<>();
180+
List<Integer> t = new ArrayList<>();
181+
for (int i = 0; i < m * n; ++i) {
182+
if (land[i / n][i % n] != 0) {
183+
continue;
184+
}
185+
int root = find(i);
186+
if (!s.contains(root)) {
187+
s.add(root);
188+
t.add(size[root]);
189+
}
190+
}
191+
Collections.sort(t);
192+
int[] res = new int[t.size()];
193+
for (int i = 0; i < res.length; ++i) {
194+
res[i] = t.get(i);
195+
}
196+
return res;
197+
}
198+
199+
private int find(int x) {
200+
if (p[x] != x) {
201+
p[x] = find(p[x]);
202+
}
203+
return p[x];
204+
}
205+
206+
private void union(int a, int b) {
207+
int pa = find(a), pb = find(b);
208+
if (pa == pb) {
209+
return;
210+
}
211+
size[pb] += size[pa];
212+
p[pa] = pb;
213+
}
214+
}
215+
```
216+
217+
### **C++**
218+
219+
```cpp
220+
class Solution {
221+
public:
222+
vector<int> p;
223+
vector<int> size;
224+
225+
vector<int> pondSizes(vector<vector<int>>& land) {
226+
int m = land.size(), n = land[0].size();
227+
for (int i = 0; i < m * n; ++i)
228+
{
229+
p.push_back(i);
230+
size.push_back(1);
231+
}
232+
for (int i = 0; i < m; ++i)
233+
{
234+
for (int j = 0; j < n; ++j)
235+
{
236+
if (land[i][j] != 0) continue;
237+
int idx = i * n + j;
238+
if (i < m - 1 && land[i + 1][j] == 0) unite(idx, (i + 1) * n + j);
239+
if (j < n - 1 && land[i][j + 1] == 0) unite(idx, i * n + j + 1);
240+
if (i < m - 1 && j < n - 1 && land[i + 1][j + 1] == 0) unite(idx, (i + 1) * n + j + 1);
241+
if (i < m - 1 && j > 0 && land[i + 1][j - 1] == 0) unite(idx, (i + 1) * n + j - 1);
242+
}
243+
}
244+
unordered_set<int> s;
245+
vector<int> res;
246+
for (int i = 0; i < m * n; ++i) {
247+
if (land[i / n][i % n] != 0) continue;
248+
int root = find(i);
249+
if (s.find(root) == s.end()) {
250+
s.insert(root);
251+
res.push_back(size[root]);
252+
}
253+
}
254+
sort(res.begin(), res.end());
255+
return res;
256+
}
257+
258+
int find(int x) {
259+
if (p[x] != x) p[x] = find(p[x]);
260+
return p[x];
261+
}
262+
263+
void unite(int a, int b) {
264+
int pa = find(a), pb = find(b);
265+
if (pa == pb) return;
266+
size[pb] += size[pa];
267+
p[pa] = pb;
268+
}
269+
};
270+
```
271+
272+
### **Go**
273+
274+
```go
275+
var p []int
276+
var size []int
277+
278+
func pondSizes(land [][]int) []int {
279+
m, n := len(land), len(land[0])
280+
p = make([]int, m*n)
281+
size = make([]int, m*n)
282+
for i := 0; i < m*n; i++ {
283+
p[i] = i
284+
size[i] = 1
285+
}
286+
for i := 0; i < m; i++ {
287+
for j := 0; j < n; j++ {
288+
if land[i][j] != 0 {
289+
continue
290+
}
291+
idx := i*n + j
292+
if i < m-1 && land[i+1][j] == 0 {
293+
union(idx, (i+1)*n+j)
294+
}
295+
if j < n-1 && land[i][j+1] == 0 {
296+
union(idx, i*n+j+1)
297+
}
298+
if i < m-1 && j < n-1 && land[i+1][j+1] == 0 {
299+
union(idx, (i+1)*n+j+1)
300+
}
301+
if i < m-1 && j > 0 && land[i+1][j-1] == 0 {
302+
union(idx, (i+1)*n+j-1)
303+
}
304+
}
305+
}
306+
s := make(map[int]bool)
307+
var res []int
308+
for i := 0; i < m*n; i++ {
309+
if land[i/n][i%n] != 0 {
310+
continue
311+
}
312+
root := find(i)
313+
if !s[root] {
314+
s[root] = true
315+
res = append(res, size[root])
316+
}
317+
}
318+
sort.Ints(res)
319+
return res
320+
}
321+
322+
func find(x int) int {
323+
if p[x] != x {
324+
p[x] = find(p[x])
325+
}
326+
return p[x]
327+
}
44328

329+
func union(a, b int) {
330+
pa, pb := find(a), find(b)
331+
if pa == pb {
332+
return
333+
}
334+
size[pb] += size[pa]
335+
p[pa] = pb
336+
}
45337
```
46338

47339
### **...**

0 commit comments

Comments
 (0)