LeetCode(200)-Number of Islands/寻找陆地(深度优先搜索算法)

题目:

Given a 2d grid map of '1’s (land) and '0’s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

Input:
11110
11010
11000
00000

Output: 1
Example 2:

Input:
11000
11000
00100
00011

Output: 3

翻译:

给定一个“1”(陆地)和“0”(水域)的二维网格地图,计算岛屿的数量。岛屿被水环绕,通过水平或垂直连接相邻的陆地而形成。你可以假设网格的四个边都被水包围着。

思路:

本题是求岛屿的数量,也就是说求1被0包围的块数。对于这种问题,我们采用深度优先搜索算法,也就是穷尽法。我们创建一个boolean类型的数组,用来标记对应坐标有没有被搜索过,每当我们遇见1时,那么我们就向四周拓展,登陆所有与1相连接的岛屿,并将其标记为已登陆。在我们遍历数组时,只要遇见没有登陆的岛屿,就将岛屿块数加1;

代码实现1:

class Solution {
    public int numIslands(char[][] grid) {
        if(grid==null || grid.length==0 || grid[0]==null || grid[0].length==0){
            return 0;
        }
        //记录坐标地有没有被登陆过
        boolean [][] b=new boolean[grid.length][grid[0].length];
        int num=0;
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[i].length;j++){
                //当前是岛屿且没有被登陆过。
                if(grid[i][j]=='1'&& !b[i][j]){
                    //将与之相邻的岛屿标记为已登陆
                    lands(grid, b, i, j);
                    num++;
                }
            }
        }
        return num;
    }
    private void lands(char[][] grid,boolean [][] b,int i,int j){
        //角标安全性检查
        if(i<0||i>=grid.length||j<0||j>=grid[0].length||grid[i][j]=='0'||
           //当前坐标已经被标记,没必要再去检查,前面肯定检查过
           b[i][j]){
            return ;
        }
        //将当前岛屿标记为已登陆
        b[i][j]=true;
        //向上下左右进行相邻标记
        lands(grid, b, i-1, j);
        lands(grid, b, i+1, j);
        lands(grid, b, i, j-1);
        lands(grid, b, i, j+1);
    }
}

代码实现2:

实际上我们完全可以不需要标记数组,当遇到岛屿时,将其标记为水域,这样也起到了隔离岛屿的作用。

class Solution {
    public int numIslands(char[][] grid) {
        if(grid==null || grid.length==0 || grid[0]==null || grid[0].length==0){
            return 0;
        }
        //记录坐标地有没有被登陆过
        boolean [][] b=new boolean[grid.length][grid[0].length];
        int num=0;
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[i].length;j++){
                //当前是岛屿且没有被登陆过。
                if(grid[i][j]=='1'){
                    lands(grid,  i, j);
                    num++;
                }
            }
        }
        return num;
    }
    private void lands(char[][] grid,int i,int j){
        //角标安全性检查
        if(i<0||i>=grid.length||j<0||j>=grid[0].length||grid[i][j]=='0'){
            return ;
        }
        //将当前岛屿设置为水域,
        grid[i][j]='0';
        //向上下左右进行搜索设置
        lands(grid, i-1, j);
        lands(grid, i+1, j);
        lands(grid, i, j-1);
        lands(grid, i, j+1);
    }
}

你可能感兴趣的:(LeetCode(200)-Number of Islands/寻找陆地(深度优先搜索算法))