2.题目描述:
给你一个由 '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'
算法思路:
遍历整个矩阵,每次找到「一块陆地」的时候:
| 说明找到「一个岛屿」,记录到最终结果 ret 里面; | |
| • | |
| • |
遍历到这块岛屿的时候,它「已经是海洋」了,不会影响最终结果。
| • | 其中「变成海洋」的操作,可以利用「深搜」和「宽搜」解决,其实就是 733. 图像渲染 这道题~ |
这样,当我们,遍历完全部的矩阵的时候,ret 存的就是最终结果。
解法(dfs):
算法流程:
1. 初始化ret = 0 ,记录目前找到的岛屿数量;
2. 双重循环遍历二维网格,每当遇到一块陆地,标记这是一个新的岛屿,然后将这块陆地相连的陆地 全部变成海洋。
递归函数的设计:
1. 把当前格子标记为水;
2. 向上、下、左、右四格递归寻找陆地,只有在下标位置合理的情况下,才会进入递归:
a. 下一个位置的坐标合理;
b. 并且下一个位置是陆地
Java算法代码:
class Solution {
boolean [][] vis;
int m,n;
int []dx = {0,0,-1,1};
int []dy = {1,-1,0,0};
public int numIslands(char[][] grid) {
m = grid.length; n = grid[0].length;
vis = new boolean[m][n];
int ret = 0;
for(int i = 0; i< m;i++)
for(int j = 0; j<n;j++)
if(!vis[i][j] && grid[i][j] =='1'){
ret++;
dfs(grid,i,j);
}
return ret;
}
public void dfs(char[][] grid,int i,int j){
vis[i][j] =true;
for(int k = 0; k<4;k++){
int x = i + dx[k], y = j + dy[k];
if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y]== '1')
dfs(grid,x,y);
}
}
}
运行结果:

递归展开:

逻辑展开:
这里逻辑很好理解,一个细节在于,将岛屿变为海洋。
当能理解细节时候,就可以手撸结果了。
---------------------------------------------------------------------------------------------------------------------------------
记住,相信你的递归函数,它可以做到!
记住,不理解时候,去尝试手动展开!
记住,逻辑展开(你不可能对所有的题目都进行手动展开)!
493

被折叠的 条评论
为什么被折叠?



