Skip to content

Commit 2fad043

Browse files
committed
feat: add solutions to lc problem: No.0827
No.0827.Making A Large Island
1 parent 85be9ff commit 2fad043

File tree

2 files changed

+452
-4
lines changed

2 files changed

+452
-4
lines changed

solution/0800-0899/0827.Making A Large Island/README.md

Lines changed: 235 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@
5353

5454
**方法一:并查集**
5555

56-
由题意,我们知道,相邻的 $1$ 组成一个岛屿。这涉及到一个合并的操作,也就是说,我们可以将相邻的 $1$ 合并到一个集合中。
57-
58-
这里我们可以使用并查集来实现,时间复杂度 $O(n^2\times \alpha(n))$。其中 $n$ 为矩阵的边长。
59-
6056
并查集是一种树形的数据结构,顾名思义,它用于处理一些不交集的**合并****查询**问题。 它支持两种操作:
6157

6258
1. 查找(Find):确定某个元素处于哪个子集,单次操作时间复杂度 $O(\alpha(n))$
@@ -91,6 +87,24 @@ def union(a, b):
9187
size[pb] += size[pa]
9288
```
9389

90+
在这道题中,相邻的 $1$ 组成一个岛屿,因此,我们需要将相邻的 $1$ 归到同一个集合中。这可以视为一个合并操作,不难想到用并查集来实现。
91+
92+
第一次遍历 `grid`,通过并查集的 `union` 操作合并所有相邻的 $1$,并且统计每个岛屿的面积,记录在 $size$ 数组中。
93+
94+
再次遍历 `grid`,对于每个 $0$,我们统计相邻的四个点中 $1$ 所在的岛屿(通过并查集的 `find` 操作找到所在岛屿),累加去重后的岛屿面积,更新最大值。
95+
96+
时间复杂度 $O(n^2\times \alpha(n))$。其中 $n$ 为矩阵 `grid` 的边长。
97+
98+
**方法二:DFS**
99+
100+
我们也可以通过 DFS,找到每个岛屿。
101+
102+
同一个岛屿中的所有点都属于同一个集合,我们可以用不同的 `root` 值标识不同的岛屿,用 $p$ 记录每个 $grid[i][j]$ 对应的 `root` 值,用 $cnt$ 记录每个岛屿的面积。
103+
104+
遍历 `grid`,对于每个 $0$,我们统计相邻的四个点中 $1$ 所在的岛屿(与方法一不同的是,我们这里直接取 $p[i][j]$ 作为 `root`),累加去重后的岛屿面积,更新最大值。
105+
106+
时间复杂度 $O(n^2)$。其中 $n$ 为矩阵 `grid` 的边长。
107+
94108
<!-- tabs:start -->
95109

96110
### **Python3**
@@ -139,6 +153,44 @@ class Solution:
139153
return ans
140154
```
141155

156+
```python
157+
class Solution:
158+
def largestIsland(self, grid: List[List[int]]) -> int:
159+
def dfs(i, j):
160+
p[i][j] = root
161+
cnt[root] += 1
162+
for a, b in [[0, -1], [0, 1], [-1, 0], [1, 0]]:
163+
x, y = i + a, j + b
164+
if 0 <= x < n and 0 <= y < n and grid[x][y] and p[x][y] == 0:
165+
dfs(x, y)
166+
167+
n = len(grid)
168+
cnt = Counter()
169+
p = [[0] * n for _ in range(n)]
170+
root = 0
171+
for i, row in enumerate(grid):
172+
for j, v in enumerate(row):
173+
if v and p[i][j] == 0:
174+
root += 1
175+
dfs(i, j)
176+
177+
ans = max(cnt.values(), default=0)
178+
for i, row in enumerate(grid):
179+
for j, v in enumerate(row):
180+
if v == 0:
181+
t = 1
182+
vis = set()
183+
for a, b in [[0, -1], [0, 1], [-1, 0], [1, 0]]:
184+
x, y = i + a, j + b
185+
if 0 <= x < n and 0 <= y < n:
186+
root = p[x][y]
187+
if root not in vis:
188+
vis.add(root)
189+
t += cnt[root]
190+
ans = max(ans, t)
191+
return ans
192+
```
193+
142194
### **Java**
143195

144196
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -208,6 +260,65 @@ class Solution {
208260
}
209261
```
210262

263+
```java
264+
class Solution {
265+
private int n;
266+
private int ans;
267+
private int root;
268+
private int[][] p;
269+
private int[][] grid;
270+
private int[] cnt;
271+
private int[] dirs = new int[] {-1, 0, 1, 0, -1};
272+
273+
public int largestIsland(int[][] grid) {
274+
n = grid.length;
275+
cnt = new int[n * n + 1];
276+
p = new int[n][n];
277+
this.grid = grid;
278+
for (int i = 0; i < n; ++i) {
279+
for (int j = 0; j < n; ++j) {
280+
if (grid[i][j] == 1 && p[i][j] == 0) {
281+
++root;
282+
dfs(i, j);
283+
}
284+
}
285+
}
286+
for (int i = 0; i < n; ++i) {
287+
for (int j = 0; j < n; ++j) {
288+
if (grid[i][j] == 0) {
289+
int t = 1;
290+
Set<Integer> vis = new HashSet<>();
291+
for (int k = 0; k < 4; ++k) {
292+
int x = i + dirs[k], y = j + dirs[k + 1];
293+
if (x >= 0 && x < n && y >= 0 && y < n) {
294+
int root = p[x][y];
295+
if (!vis.contains(root)) {
296+
vis.add(root);
297+
t += cnt[root];
298+
}
299+
}
300+
}
301+
ans = Math.max(ans, t);
302+
}
303+
}
304+
}
305+
return ans;
306+
}
307+
308+
private void dfs(int i, int j) {
309+
p[i][j] = root;
310+
++cnt[root];
311+
ans = Math.max(ans, cnt[root]);
312+
for (int k = 0; k < 4; ++k) {
313+
int x = i + dirs[k], y = j + dirs[k + 1];
314+
if (x >= 0 && x < n && y >= 0 && y < n && grid[x][y] == 1 && p[x][y] == 0) {
315+
dfs(x, y);
316+
}
317+
}
318+
}
319+
}
320+
```
321+
211322
### **C++**
212323

213324
```cpp
@@ -270,6 +381,64 @@ public:
270381
};
271382
```
272383

384+
```cpp
385+
class Solution {
386+
public:
387+
const static inline vector<int> dirs = {-1, 0, 1, 0, -1};
388+
389+
int largestIsland(vector<vector<int>>& grid) {
390+
int n = grid.size();
391+
int ans = 0;
392+
int root = 0;
393+
vector<vector<int>> p(n, vector<int>(n));
394+
vector<int> cnt(n * n + 1);
395+
396+
function<void(int, int)> dfs;
397+
dfs = [&](int i, int j) {
398+
p[i][j] = root;
399+
++cnt[root];
400+
ans = max(ans, cnt[root]);
401+
for (int k = 0; k < 4; ++k) {
402+
int x = i + dirs[k], y = j + dirs[k + 1];
403+
if (x >= 0 && x < n && y >= 0 && y < n && grid[x][y] && p[x][y] == 0) {
404+
dfs(x, y);
405+
}
406+
}
407+
};
408+
409+
for (int i = 0; i < n; ++i) {
410+
for (int j = 0; j < n; ++j) {
411+
if (grid[i][j] && p[i][j] == 0) {
412+
++root;
413+
dfs(i, j);
414+
}
415+
}
416+
}
417+
418+
for (int i = 0; i < n; ++i) {
419+
for (int j = 0; j < n; ++j) {
420+
if (!grid[i][j]) {
421+
int t = 1;
422+
unordered_set<int> vis;
423+
for (int k = 0; k < 4; ++k) {
424+
int x = i + dirs[k], y = j + dirs[k + 1];
425+
if (x >= 0 && x < n && y >= 0 && y < n) {
426+
int root = p[x][y];
427+
if (!vis.count(root)) {
428+
vis.insert(root);
429+
t += cnt[root];
430+
}
431+
}
432+
}
433+
ans = max(ans, t);
434+
}
435+
}
436+
}
437+
return ans;
438+
}
439+
};
440+
```
441+
273442
### **Go**
274443

275444
```go
@@ -337,6 +506,68 @@ func max(a, b int) int {
337506
}
338507
```
339508

509+
```go
510+
func largestIsland(grid [][]int) int {
511+
n := len(grid)
512+
p := make([][]int, n)
513+
for i := range p {
514+
p[i] = make([]int, n)
515+
}
516+
cnt := make([]int, n*n+1)
517+
dirs := []int{-1, 0, 1, 0, -1}
518+
ans, root := 0, 0
519+
520+
var dfs func(i, j int)
521+
dfs = func(i, j int) {
522+
p[i][j] = root
523+
cnt[root]++
524+
ans = max(ans, cnt[root])
525+
for k := 0; k < 4; k++ {
526+
x, y := i+dirs[k], j+dirs[k+1]
527+
if x >= 0 && x < n && y >= 0 && y < n && grid[x][y] == 1 && p[x][y] == 0 {
528+
dfs(x, y)
529+
}
530+
}
531+
}
532+
533+
for i, row := range grid {
534+
for j, v := range row {
535+
if v == 1 && p[i][j] == 0 {
536+
root++
537+
dfs(i, j)
538+
}
539+
}
540+
}
541+
for i, row := range grid {
542+
for j, v := range row {
543+
if v == 0 {
544+
t := 1
545+
vis := map[int]struct{}{}
546+
for k := 0; k < 4; k++ {
547+
x, y := i+dirs[k], j+dirs[k+1]
548+
if x >= 0 && x < n && y >= 0 && y < n {
549+
root := p[x][y]
550+
if _, ok := vis[root]; !ok {
551+
vis[root] = struct{}{}
552+
t += cnt[root]
553+
}
554+
}
555+
}
556+
ans = max(ans, t)
557+
}
558+
}
559+
}
560+
return ans
561+
}
562+
563+
func max(a, b int) int {
564+
if a > b {
565+
return a
566+
}
567+
return b
568+
}
569+
```
570+
340571
### **...**
341572

342573
```

0 commit comments

Comments
 (0)