在做蓝桥杯这道题时,看题解,发现和力扣上一道“岛屿数量”很像很像,于是乎,先去把力扣上这道题搞懂了,蓝桥杯这道题就相对来说简单了。其实核心是图论中的深度优先法(DFS)。
做这道题之前呢,先分析一波力扣上的这道题,也是熟练DFS了。(借鉴自代码随想录深搜版)
岛屿数量
给你一个由 '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'
这道题DFS和BFS(广度优先搜索)都能做,下面先给出DFS版的代码,再给出BFS版本的,其中DFS有两种方法:1. 利用visited数组标记法。2. 染色法(把走过的路染色成字符0,省去了多开辟一个数组的空间)
DFS法1(标记数组):
class Solution {
boolean[][] visited; // 标记是否走过,初始时,默认为false都没走过
int[][] dir = {
{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public int numIslands(char[][] grid) {
// 与广搜的思路一样,外面先来个遍历,里面深搜判断岛屿
int count = 0;
visited = new boolean[grid.length][grid[0].length]; // 初始值默认都为false
for(int i = 0; i < grid.length; i++) {
for(int j = 0; j < grid[i].length; j++) {
if(!visited[i][j] && grid[i][j] == '1') { // !visited[i][j]表示遇到的第一个没走过的坐标(i, j)之后
visited[i][j] = true;
dfs(grid, i, j); // 把以(i, j)为起始点的岛屿全部遍历一遍,并把对应的visited标记为true
count++;