From 3afd2c4704417c29df71c277f9111a8b8276698a Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Tue, 9 Dec 2025 07:26:27 +0800 Subject: [PATCH] feat: update solutions to lc problem: No.0200 --- .../0200.Number of Islands/README.md | 160 +++++++----------- .../0200.Number of Islands/README_EN.md | 129 +++++++------- .../0200.Number of Islands/Solution.cpp | 4 +- .../0200.Number of Islands/Solution.cs | 61 +++---- .../0200.Number of Islands/Solution.ts | 20 ++- .../0200.Number of Islands/Solution2.cpp | 5 +- .../0200.Number of Islands/Solution2.ts | 11 +- .../0200.Number of Islands/Solution3.ts | 9 +- 8 files changed, 185 insertions(+), 214 deletions(-) diff --git a/solution/0200-0299/0200.Number of Islands/README.md b/solution/0200-0299/0200.Number of Islands/README.md index 970293b67ab70..b6b443751e014 100644 --- a/solution/0200-0299/0200.Number of Islands/README.md +++ b/solution/0200-0299/0200.Number of Islands/README.md @@ -69,13 +69,11 @@ tags: -### 方法一:Flood fill 算法 +### 方法一:DFS -Flood fill 算法是从一个区域中提取若干个连通的点与其他相邻区域区分开(或分别染成不同颜色)的经典算法。因为其思路类似洪水从一个区域扩散到所有能到达的区域而得名。 +我们可以使用深度优先搜索(DFS)来遍历每个岛屿。遍历网格中的每个单元格 $(i, j)$,如果该单元格的值为 '1',则说明我们找到了一个新的岛屿。我们可以从该单元格开始进行 DFS,将与之相连的所有陆地单元格的值都标记为 '0',以避免重复计数。每次找到一个新的岛屿时,我们将岛屿数量加 1。 -最简单的实现方法是采用 DFS 的递归方法,也可以采用 BFS 的迭代来实现。 - -时间复杂度 $O(m\times n)$,空间复杂度 $O(m\times n)$。其中 $m$ 和 $n$ 分别为网格的行数和列数。 +时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为网格的行数和列数。 @@ -150,7 +148,7 @@ public: int n = grid[0].size(); int ans = 0; int dirs[5] = {-1, 0, 1, 0, -1}; - function dfs = [&](int i, int j) { + auto dfs = [&](this auto&& dfs, int i, int j) -> void { grid[i][j] = '0'; for (int k = 0; k < 4; ++k) { int x = i + dirs[k], y = j + dirs[k + 1]; @@ -208,24 +206,28 @@ function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; let ans = 0; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number) => { - if (grid[i]?.[j] !== '1') { - return; - } grid[i][j] = '0'; - dfs(i + 1, j); - dfs(i - 1, j); - dfs(i, j + 1); - dfs(i, j - 1); + for (let k = 0; k < 4; ++k) { + const x = i + dirs[k]; + const y = j + dirs[k + 1]; + if (grid[x]?.[y] === '1') { + dfs(x, y); + } + } }; + for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { if (grid[i][j] === '1') { dfs(i, j); - ++ans; + ans++; } } } + return ans; } ``` @@ -271,44 +273,37 @@ impl Solution { #### C# ```cs -using System; -using System.Collections.Generic; -using System.Linq; - public class Solution { - public int NumIslands(char[][] grid) - { - var queue = new Queue>(); - var lenI = grid.Length; - var lenJ = lenI == 0 ? 0 : grid[0].Length; - var paths = new int[,] { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; - var result = 0; - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (grid[i][j] == '1') + public int NumIslands(char[][] grid) { + int m = grid.Length; + int n = grid[0].Length; + int ans = 0; + int[] dirs = { -1, 0, 1, 0, -1 }; + + void Dfs(int i, int j) { + grid[i][j] = '0'; + for (int k = 0; k < 4; ++k) { + int x = i + dirs[k]; + int y = j + dirs[k + 1]; + if (x >= 0 && x < m && + y >= 0 && y < n && + grid[x][y] == '1') { - ++result; - grid[i][j] = '0'; - queue.Enqueue(Tuple.Create(i, j)); - while (queue.Any()) - { - var position = queue.Dequeue(); - for (var k = 0; k < 4; ++k) - { - var next = Tuple.Create(position.Item1 + paths[k, 0], position.Item2 + paths[k, 1]); - if (next.Item1 >= 0 && next.Item1 < lenI && next.Item2 >= 0 && next.Item2 < lenJ && grid[next.Item1][next.Item2] == '1') - { - grid[next.Item1][next.Item2] = '0'; - queue.Enqueue(next); - } - } - } + Dfs(x, y); } } } - return result; + + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid[i][j] == '1') { + Dfs(i, j); + ans++; + } + } + } + + return ans; } } ``` @@ -319,44 +314,18 @@ public class Solution { -### 方法二:并查集 - -并查集是一种树形的数据结构,顾名思义,它用于处理一些不交集的**合并**及**查询**问题。 它支持两种操作: - -1. 查找(Find):确定某个元素处于哪个子集,单次操作时间复杂度 $O(\alpha(n))$ -1. 合并(Union):将两个子集合并成一个集合,单次操作时间复杂度 $O(\alpha(n))$ - -其中 $\alpha$ 为阿克曼函数的反函数,其增长极其缓慢,也就是说其单次操作的平均运行时间可以认为是一个很小的常数。 - -以下是并查集的常用模板,需要熟练掌握。其中: - -- `n` 表示节点数 -- `p` 存储每个点的父节点,初始时每个点的父节点都是自己 -- `size` 只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量 -- `find(x)` 函数用于查找 $x$ 所在集合的祖宗节点 -- `union(a, b)` 函数用于合并 $a$ 和 $b$ 所在的集合 - -```python -p = list(range(n)) -size = [1] * n +### 方法二:BFS +我们也可以使用广度优先搜索(BFS)来遍历每个岛屿。遍历网格中的每个单元格 $(i, j)$,如果该单元格的值为 '1',则说明我们找到了一个新的岛屿。我们可以从该单元格开始进行 BFS,将与之相连的所有陆地单元格的值都标记为 '0',以避免重复计数。每次找到一个新的岛屿时,我们将岛屿数量加 1。 -def find(x): - if p[x] != x: - # 路径压缩 - p[x] = find(p[x]) - return p[x] +BFS 的具体过程如下: +1. 将起始单元格 $(i, j)$ 入队,并将其值标记为 '0'。 +2. 当队列不为空时,执行以下操作: + - 出队一个单元格 $p$。 + - 遍历 $p$ 的四个相邻单元格 $(x, y)$,如果 $(x, y)$ 在网格范围内且值为 '1',则将其入队并将其值标记为 '0'。 -def union(a, b): - pa, pb = find(a), find(b) - if pa == pb: - return - p[pa] = pb - size[pb] += size[pa] -``` - -时间复杂度 $O(m\times n\times \alpha(m\times n))$。其中 $m$ 和 $n$ 分别为网格的行数和列数。 +时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为网格的行数和列数。 @@ -441,11 +410,10 @@ public: int n = grid[0].size(); int ans = 0; int dirs[5] = {-1, 0, 1, 0, -1}; - function bfs = [&](int i, int j) { + auto bfs = [&](int i, int j) -> void { grid[i][j] = '0'; queue> q; q.push({i, j}); - vector dirs = {-1, 0, 1, 0, -1}; while (!q.empty()) { auto [a, b] = q.front(); q.pop(); @@ -513,22 +481,21 @@ function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; let ans = 0; - function bfs(i, j) { + const bfs = (i: number, j: number) => { grid[i][j] = '0'; - let q = [[i, j]]; + const q = [[i, j]]; const dirs = [-1, 0, 1, 0, -1]; - while (q.length) { - [i, j] = q.shift(); + for (const [i, j] of q) { for (let k = 0; k < 4; ++k) { const x = i + dirs[k]; const y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1') { + if (grid[x]?.[y] == '1') { q.push([x, y]); grid[x][y] = '0'; } } } - } + }; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { if (grid[i][j] == '1') { @@ -592,7 +559,11 @@ impl Solution { -### 方法三 +### 方法三: 并查集 + +我们可以使用并查集(Union-Find)来解决这个问题。遍历网格中的每个单元格 $(i, j)$,如果该单元格的值为 '1',则将其与相邻的陆地单元格进行合并。最后,我们统计并查集中不同根节点的数量,即为岛屿的数量。 + +时间复杂度 $O(m \times n \times \log (m \times n))$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为网格的行数和列数。 @@ -758,11 +729,8 @@ func numIslands(grid [][]byte) int { function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; - let p = []; - for (let i = 0; i < m * n; ++i) { - p.push(i); - } - function find(x) { + const p: number[] = Array.from({ length: m * n }, (_, i) => i); + function find(x: number): number { if (p[x] != x) { p[x] = find(p[x]); } @@ -775,7 +743,7 @@ function numIslands(grid: string[][]): number { for (let k = 0; k < 2; ++k) { const x = i + dirs[k]; const y = j + dirs[k + 1]; - if (x < m && y < n && grid[x][y] == '1') { + if (grid[x]?.[y] == '1') { p[find(i * n + j)] = find(x * n + y); } } diff --git a/solution/0200-0299/0200.Number of Islands/README_EN.md b/solution/0200-0299/0200.Number of Islands/README_EN.md index b89c69dd4170a..58d9bf63c9d51 100644 --- a/solution/0200-0299/0200.Number of Islands/README_EN.md +++ b/solution/0200-0299/0200.Number of Islands/README_EN.md @@ -65,7 +65,11 @@ tags: -### Solution 1 +### Solution 1: DFS + +We can use depth-first search (DFS) to traverse each island. We iterate through each cell $(i, j)$ in the grid. If the cell's value is '1', it means we have found a new island. We can start a DFS from this cell, marking all connected land cells as '0' to avoid duplicate counting. Each time we find a new island, we increment the island count by 1. + +The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Where $m$ and $n$ are the number of rows and columns in the grid, respectively. @@ -140,7 +144,7 @@ public: int n = grid[0].size(); int ans = 0; int dirs[5] = {-1, 0, 1, 0, -1}; - function dfs = [&](int i, int j) { + auto dfs = [&](this auto&& dfs, int i, int j) -> void { grid[i][j] = '0'; for (int k = 0; k < 4; ++k) { int x = i + dirs[k], y = j + dirs[k + 1]; @@ -198,24 +202,28 @@ function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; let ans = 0; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number) => { - if (grid[i]?.[j] !== '1') { - return; - } grid[i][j] = '0'; - dfs(i + 1, j); - dfs(i - 1, j); - dfs(i, j + 1); - dfs(i, j - 1); + for (let k = 0; k < 4; ++k) { + const x = i + dirs[k]; + const y = j + dirs[k + 1]; + if (grid[x]?.[y] === '1') { + dfs(x, y); + } + } }; + for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { if (grid[i][j] === '1') { dfs(i, j); - ++ans; + ans++; } } } + return ans; } ``` @@ -261,44 +269,37 @@ impl Solution { #### C# ```cs -using System; -using System.Collections.Generic; -using System.Linq; - public class Solution { - public int NumIslands(char[][] grid) - { - var queue = new Queue>(); - var lenI = grid.Length; - var lenJ = lenI == 0 ? 0 : grid[0].Length; - var paths = new int[,] { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; - var result = 0; - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (grid[i][j] == '1') + public int NumIslands(char[][] grid) { + int m = grid.Length; + int n = grid[0].Length; + int ans = 0; + int[] dirs = { -1, 0, 1, 0, -1 }; + + void Dfs(int i, int j) { + grid[i][j] = '0'; + for (int k = 0; k < 4; ++k) { + int x = i + dirs[k]; + int y = j + dirs[k + 1]; + if (x >= 0 && x < m && + y >= 0 && y < n && + grid[x][y] == '1') { - ++result; - grid[i][j] = '0'; - queue.Enqueue(Tuple.Create(i, j)); - while (queue.Any()) - { - var position = queue.Dequeue(); - for (var k = 0; k < 4; ++k) - { - var next = Tuple.Create(position.Item1 + paths[k, 0], position.Item2 + paths[k, 1]); - if (next.Item1 >= 0 && next.Item1 < lenI && next.Item2 >= 0 && next.Item2 < lenJ && grid[next.Item1][next.Item2] == '1') - { - grid[next.Item1][next.Item2] = '0'; - queue.Enqueue(next); - } - } - } + Dfs(x, y); } } } - return result; + + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid[i][j] == '1') { + Dfs(i, j); + ans++; + } + } + } + + return ans; } } ``` @@ -309,7 +310,18 @@ public class Solution { -### Solution 2 +### Solution 2: BFS + +We can also use breadth-first search (BFS) to traverse each island. We iterate through each cell $(i, j)$ in the grid. If the cell's value is '1', it means we have found a new island. We can start a BFS from this cell, marking all connected land cells as '0' to avoid duplicate counting. Each time we find a new island, we increment the island count by 1. + +The specific BFS process is as follows: + +1. Enqueue the starting cell $(i, j)$ and mark its value as '0'. +2. While the queue is not empty, perform the following operations: + - Dequeue a cell $p$. + - Iterate through the four adjacent cells $(x, y)$ of $p$. If $(x, y)$ is within the grid bounds and its value is '1', enqueue it and mark its value as '0'. + +The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Where $m$ and $n$ are the number of rows and columns in the grid, respectively. @@ -394,11 +406,10 @@ public: int n = grid[0].size(); int ans = 0; int dirs[5] = {-1, 0, 1, 0, -1}; - function bfs = [&](int i, int j) { + auto bfs = [&](int i, int j) -> void { grid[i][j] = '0'; queue> q; q.push({i, j}); - vector dirs = {-1, 0, 1, 0, -1}; while (!q.empty()) { auto [a, b] = q.front(); q.pop(); @@ -466,22 +477,21 @@ function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; let ans = 0; - function bfs(i, j) { + const bfs = (i: number, j: number) => { grid[i][j] = '0'; - let q = [[i, j]]; + const q = [[i, j]]; const dirs = [-1, 0, 1, 0, -1]; - while (q.length) { - [i, j] = q.shift(); + for (const [i, j] of q) { for (let k = 0; k < 4; ++k) { const x = i + dirs[k]; const y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1') { + if (grid[x]?.[y] == '1') { q.push([x, y]); grid[x][y] = '0'; } } } - } + }; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { if (grid[i][j] == '1') { @@ -545,7 +555,11 @@ impl Solution { -### Solution 3 +### Solution 3: Union-Find + +We can use the Union-Find data structure to solve this problem. We traverse each cell $(i, j)$ in the grid, and if the cell's value is '1', we merge it with adjacent land cells. Finally, we count the number of distinct root nodes in the Union-Find structure, which represents the number of islands. + +The time complexity is $O(m \times n \times \log (m \times n))$, and the space complexity is $O(m \times n)$. Where $m$ and $n$ are the number of rows and columns in the grid, respectively. @@ -711,11 +725,8 @@ func numIslands(grid [][]byte) int { function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; - let p = []; - for (let i = 0; i < m * n; ++i) { - p.push(i); - } - function find(x) { + const p: number[] = Array.from({ length: m * n }, (_, i) => i); + function find(x: number): number { if (p[x] != x) { p[x] = find(p[x]); } @@ -728,7 +739,7 @@ function numIslands(grid: string[][]): number { for (let k = 0; k < 2; ++k) { const x = i + dirs[k]; const y = j + dirs[k + 1]; - if (x < m && y < n && grid[x][y] == '1') { + if (grid[x]?.[y] == '1') { p[find(i * n + j)] = find(x * n + y); } } diff --git a/solution/0200-0299/0200.Number of Islands/Solution.cpp b/solution/0200-0299/0200.Number of Islands/Solution.cpp index 49116daebb518..d4cdba52bb3ce 100644 --- a/solution/0200-0299/0200.Number of Islands/Solution.cpp +++ b/solution/0200-0299/0200.Number of Islands/Solution.cpp @@ -5,7 +5,7 @@ class Solution { int n = grid[0].size(); int ans = 0; int dirs[5] = {-1, 0, 1, 0, -1}; - function dfs = [&](int i, int j) { + auto dfs = [&](this auto&& dfs, int i, int j) -> void { grid[i][j] = '0'; for (int k = 0; k < 4; ++k) { int x = i + dirs[k], y = j + dirs[k + 1]; @@ -24,4 +24,4 @@ class Solution { } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0200-0299/0200.Number of Islands/Solution.cs b/solution/0200-0299/0200.Number of Islands/Solution.cs index c6ecd934cc379..b0fd37a803649 100644 --- a/solution/0200-0299/0200.Number of Islands/Solution.cs +++ b/solution/0200-0299/0200.Number of Islands/Solution.cs @@ -1,40 +1,33 @@ -using System; -using System.Collections.Generic; -using System.Linq; - public class Solution { - public int NumIslands(char[][] grid) - { - var queue = new Queue>(); - var lenI = grid.Length; - var lenJ = lenI == 0 ? 0 : grid[0].Length; - var paths = new int[,] { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; - var result = 0; - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (grid[i][j] == '1') + public int NumIslands(char[][] grid) { + int m = grid.Length; + int n = grid[0].Length; + int ans = 0; + int[] dirs = { -1, 0, 1, 0, -1 }; + + void Dfs(int i, int j) { + grid[i][j] = '0'; + for (int k = 0; k < 4; ++k) { + int x = i + dirs[k]; + int y = j + dirs[k + 1]; + if (x >= 0 && x < m && + y >= 0 && y < n && + grid[x][y] == '1') { - ++result; - grid[i][j] = '0'; - queue.Enqueue(Tuple.Create(i, j)); - while (queue.Any()) - { - var position = queue.Dequeue(); - for (var k = 0; k < 4; ++k) - { - var next = Tuple.Create(position.Item1 + paths[k, 0], position.Item2 + paths[k, 1]); - if (next.Item1 >= 0 && next.Item1 < lenI && next.Item2 >= 0 && next.Item2 < lenJ && grid[next.Item1][next.Item2] == '1') - { - grid[next.Item1][next.Item2] = '0'; - queue.Enqueue(next); - } - } - } + Dfs(x, y); } } } - return result; + + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid[i][j] == '1') { + Dfs(i, j); + ans++; + } + } + } + + return ans; } -} \ No newline at end of file +} diff --git a/solution/0200-0299/0200.Number of Islands/Solution.ts b/solution/0200-0299/0200.Number of Islands/Solution.ts index 8ac5367be98ac..859ee0baa0630 100644 --- a/solution/0200-0299/0200.Number of Islands/Solution.ts +++ b/solution/0200-0299/0200.Number of Islands/Solution.ts @@ -2,23 +2,27 @@ function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; let ans = 0; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number) => { - if (grid[i]?.[j] !== '1') { - return; - } grid[i][j] = '0'; - dfs(i + 1, j); - dfs(i - 1, j); - dfs(i, j + 1); - dfs(i, j - 1); + for (let k = 0; k < 4; ++k) { + const x = i + dirs[k]; + const y = j + dirs[k + 1]; + if (grid[x]?.[y] === '1') { + dfs(x, y); + } + } }; + for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { if (grid[i][j] === '1') { dfs(i, j); - ++ans; + ans++; } } } + return ans; } diff --git a/solution/0200-0299/0200.Number of Islands/Solution2.cpp b/solution/0200-0299/0200.Number of Islands/Solution2.cpp index 3b1157ec545e9..4ff04b9ef0736 100644 --- a/solution/0200-0299/0200.Number of Islands/Solution2.cpp +++ b/solution/0200-0299/0200.Number of Islands/Solution2.cpp @@ -5,11 +5,10 @@ class Solution { int n = grid[0].size(); int ans = 0; int dirs[5] = {-1, 0, 1, 0, -1}; - function bfs = [&](int i, int j) { + auto bfs = [&](int i, int j) -> void { grid[i][j] = '0'; queue> q; q.push({i, j}); - vector dirs = {-1, 0, 1, 0, -1}; while (!q.empty()) { auto [a, b] = q.front(); q.pop(); @@ -33,4 +32,4 @@ class Solution { } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0200-0299/0200.Number of Islands/Solution2.ts b/solution/0200-0299/0200.Number of Islands/Solution2.ts index 03a5d20cc071b..592283ebdac18 100644 --- a/solution/0200-0299/0200.Number of Islands/Solution2.ts +++ b/solution/0200-0299/0200.Number of Islands/Solution2.ts @@ -2,22 +2,21 @@ function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; let ans = 0; - function bfs(i, j) { + const bfs = (i: number, j: number) => { grid[i][j] = '0'; - let q = [[i, j]]; + const q = [[i, j]]; const dirs = [-1, 0, 1, 0, -1]; - while (q.length) { - [i, j] = q.shift(); + for (const [i, j] of q) { for (let k = 0; k < 4; ++k) { const x = i + dirs[k]; const y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1') { + if (grid[x]?.[y] == '1') { q.push([x, y]); grid[x][y] = '0'; } } } - } + }; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { if (grid[i][j] == '1') { diff --git a/solution/0200-0299/0200.Number of Islands/Solution3.ts b/solution/0200-0299/0200.Number of Islands/Solution3.ts index 4bd106f2a028f..cfc435e1d06dc 100644 --- a/solution/0200-0299/0200.Number of Islands/Solution3.ts +++ b/solution/0200-0299/0200.Number of Islands/Solution3.ts @@ -1,11 +1,8 @@ function numIslands(grid: string[][]): number { const m = grid.length; const n = grid[0].length; - let p = []; - for (let i = 0; i < m * n; ++i) { - p.push(i); - } - function find(x) { + const p: number[] = Array.from({ length: m * n }, (_, i) => i); + function find(x: number): number { if (p[x] != x) { p[x] = find(p[x]); } @@ -18,7 +15,7 @@ function numIslands(grid: string[][]): number { for (let k = 0; k < 2; ++k) { const x = i + dirs[k]; const y = j + dirs[k + 1]; - if (x < m && y < n && grid[x][y] == '1') { + if (grid[x]?.[y] == '1') { p[find(i * n + j)] = find(x * n + y); } }