题目
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [ ["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1
示例 2:
输入:grid = [ ["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j] 的值为 '0' 或 '1'
思路:深度递归 + 四叉树搜索
function numIslands(grid: string[][]): number {
let islands = 0;
// 异常处理
if(!grid || !grid.length || !grid[0] || !grid[0].length) return islands;
// 标记位
const m = grid.length;
const n = grid[0].length;
const visited = new Array(m).fill(false).map(d => {
return new Array(n).fill(false);
});
// DFS
const dfs = (i, j) => {
// 终止条件:越界,遇到水,标记过
if(i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || grid[i][j] === '0') return;
// 标记
visited[i][j] = true;
// 四叉树搜索
dfs(i, j - 1)
dfs(i, j + 1)
dfs(i + 1, j)
dfs(i - 1, j)
}
// 行列遍历
for(let i = 0; i < m; i++) {
for(let j = 0; j < n; j++) {
// 新的岛屿
if(!visited[i][j] && grid[i][j] === '1') {
islands++;
dfs(i, j);
}
}
}
return islands;
};
总结
- 时间复杂度:O(mn),其中 m 和 n 分别是二维网格地图的行数和列数。最坏情况下,我们需要遍历整个二维网格地图才能计算岛屿数量。
- 空间复杂度:O(mn),其中 m 和 n 分别是二维网格地图的行数和列数。在最坏情况下,整个二维网格地图均为陆地,此时递归深度达到 mn,标记数组 visited 占用 O(mn) 的额外空间。
- 本题是一道比较典型的深度优先搜索(DFS)或广度优先搜索(BFS)的应用题,我们可以采用 DFS 或 BFS 的方式来解决这个问题。时间复杂度为 O(mn),空间复杂度为 O(mn)。