1. 题目描述
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:[['1','1','1','1','0'],['1','1','0','1','0'],['1','1','0','0','0'],['0','0','0','0','0']]输出: 1
示例 2:
输入:[['1','1','0','0','0'],['1','1','0','0','0'],['0','0','1','0','0'],['0','0','0','1','1']]输出: 3解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。
2. 解题思路
这个题目的描述很多,实际上就是说,所有在水平和竖直方向连在一起的算是一个岛屿,我们只要计算岛屿的数量即可。
- 使用深度优先遍历,遍历所有的元素,如果一个元素是1,就遍历其周围元素将其在水平与数值方向的周围元素值为1的都变为0,然后累加岛屿的数量。
使用广度优先遍历,将当前遍历到的元素存入到队列中,然后检查其上下左右的元素,如果是1,就放进队列,并将其变为0。一直取队列最后的元素进行上下左右的检查。
3. 代码实现
DFS:
/*** @param {character[][]} grid* @return {number}*/var numIslands = function(grid) {if(grid.length < 1){return 0}let isLands = 0for(let i = 0; i< grid.length; i++){for(let j = 0; j< grid[0].length; j++){if(grid[i][j] == 1){isLands++// 遍历其周围的岛屿,如果是1,就将其变为0dfs(grid, i, j)}}}return isLands};// 深度优先遍历,分别遍历元素的上下左右四个元素,如果是1,就变成0var dfs = function(grid, i, j){grid[i][j] = 0if(grid[i-1] && grid[i-1][j] == 1){dfs(grid, i-1, j)}if(grid[i+1] && grid[i+1][j] == 1){dfs(grid, i+1, j)}if(grid[i][j-1] && grid[i][j-1] == 1){dfs(grid, i, j-1)}if(grid[i][j+1] && grid[i][j+1] == 1){dfs(grid, i, j+1)}}
BFS:
/*** @param {character[][]} grid* @return {number}*/var numIslands = function(grid) {if(grid.length < 1){return 0}let isLands = 0let len1 = grid.lengthlet len2 = grid[0].lengthfor(let i = 0; i< len1; i++){for(let j = 0; j< len2; j++){if(grid[i][j] == 1){isLands++grid[i][j] = 0 // 将当前元素置为0,避免重复遍历let queue = []queue.push([i, j])while(queue.length > 0){let cur = queue.shift() // 取出队列最后面的元素let x = cur[0], y = cur[1]// 对元素进行上下左右检查if(x-1 >= 0 && grid[x-1][y] == 1){queue.push([x-1,y])grid[x-1][y] = 0}if(x+1 < len1 && grid[x+1][y] == 1){queue.push([x+1,y])grid[x+1][y] = 0}if(y-1 >= 0 && grid[x][y-1] == 1){queue.push([x,y-1])grid[x][y-1] = 0}if(y+1 < len2 && grid[x][y+1] == 1){queue.push([x,y+1])grid[x][y+1] = 0}}}}}return isLands};
4. 提交结果
DFS:

BFS:
