1. 问题描述:
给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-islands
2. 思路分析:
① 这道题目是一道经典实用dfs解决的问题,其中使用到了dfs的检查连通性的特点,计算出所有联通的陆地,凡是dfs能够到达的地方说明是可以联通的,所以基于这个想法我们可以遍历数组,找到当前的陆地,进行dfs搜索,根据题目的要求,我们可以在上下左右四个方向进行搜索,凡是能够到达的陆地我们都可以置为‘1’这样我们就省去了标记数组的步骤了,因为陆地变为水之后下一次就不能够到达这个地方了所以不用数组标记了,等到for循环中的所有的dfs结束那么最终所有的陆地就变为水了,这个时候dfs调用的次数就是岛屿的数量,其实思路还是标记简单,实现起来也不复杂
② 可以使用两个数组来表示上下左右四个方向这样就可以很方便使用for循环来表示四个平行状态进行dfs搜索
3. 代码如下:
import java.util.Scanner;
public class Solution {
public int numIslands(char[][] grid) {
int r = grid.length;
if (r == 0) return 0;
int c = grid[0].length;
int count = 0;
for (int i = 0; i < r; ++i){
for (int j = 0; j < c; ++j){
if (grid[i][j] == '1'){
dfs(grid, i, j, r, c);
count++;
}
}
}
return count;
}
/*上下左右四个方向*/
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
private void dfs(char[][] grid, int i, int j, int r, int c) {
/*将水变为陆地*/
grid[i][j] = '0';
for (int k = 0; k < 4; ++k){
int x = i + dx[k];
int y = j + dy[k];
/*先判断再决定是否递归下去*/
if (x >= 0 && x < r && y >= 0 && y < c && grid[x][y] == '1')
dfs(grid, x, y, r, c);
}
}
}