LeetBook——栈和队列——岛屿数量

岛屿数量

给你一个由 ‘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’

  • 遍历数组的每一个元素,如果遇到岛屿,岛屿数量加1,并将这一整块岛屿都标记下,表示已经计数过了,避免重复计数
  • 将整块岛屿都标记的方法是遍历整个岛屿,将每个元素都标记。可以采用BFS或DFS。

BFS


//BFS
	public int numIslands(char[][] grid) {

        if (grid == null || grid.length == 0) {
            return 0;
        }
        
        int nr = grid.length;  //row  行数
        int nc = grid[0].length;  //colnmn 列数
        int islandNumber = 0;   //统计岛屿数量


        for( int r = 0 ; r < nr ; ++r){
            for( int c = 0 ; c < nc ; ++c){         //双层循环,确保每个元素被遍历
                if(grid[r][c] == '1'){      //如果摸到了岛屿,岛屿数量加一,通过BFS遍历整个岛屿并且标记。表示该岛屿已经被计数过。避免重复计数
                    ArrayDeque<Integer> neighbors = new ArrayDeque<>();
                    neighbors.add( r * nc + c  );   //用id保存元素的行标和列标
                    grid[r][c] = '2';   //访问过的岛屿就置为二,方便区分是否访问过,如果置为0就和水区分不开了,入队时就置为2,如果出队时才置为2,一个元素可能重复入队
                    ++islandNumber;

                    while (!neighbors.isEmpty()){       //当队列不为空,通过BFS遍历整个岛屿并且标记,队列为空了,说明整块岛屿遍历完了
                        int id  = neighbors.remove();
                        int row = id / nc;
                        int colnmn = id % nc;

                        //将正在处理的岛屿四周的未访问过岛屿也加进队列
                        if(row-1 >=0  && grid[row-1][colnmn] == '1'){    //判断上方元素是否应入队
                            neighbors.add(colnmn + nc * (row-1) );
                            grid[row-1][colnmn] = '2';   //如果出队时才置为2,一个元素可能重复入队
                        }

                        if(row+1 < nr && grid[row+1][colnmn] == '1'){  //判断下方元素是否应入队
                            neighbors.add(colnmn + nc * (row+1) );
                            grid[row+1][colnmn] = '2';   //如果出队时才置为2,一个元素可能重复入队
                        }

                        if(colnmn-1 >=0 && grid[row][colnmn-1] == '1'){   //判断左方元素是否应入队
                            neighbors.add(colnmn-1 + row * nc );
                            grid[row][colnmn-1] = '2';   //如果出队时才置为2,一个元素可能重复入队
                        }

                        if(colnmn+1 < nc && grid[row][colnmn+1] == '1'){   //判断右方元素是否应入队
                            neighbors.add(colnmn+1 + row * nc );
                            grid[row][colnmn+1] = '2';   //如果出队时才置为2,一个元素可能重复入队
                        }

                    }//while (!neighbors.isEmpty())
                }// if(grid[r][c] == '1')
            }
        }//双层for
        return islandNumber;
    }

DFS

public class NumberOfIslandsSta {

    public int numIslands(char[][] grid) {

        if (grid == null || grid.length == 0) {
            return 0;
        }

        int nr = grid.length;  //row  行数
        int nc = grid[0].length;  //colnmn 列数
        int islandNumber = 0;   //统计岛屿数量
        
        for( int r = 0 ; r < nr ; ++r){
            for( int c = 0 ; c < nc ; ++c){         //双层循环,确保每个元素被遍历
                if(grid[r][c] == '1'){      //如果摸到了岛屿,岛屿数量加一,通过BFS遍历整个岛屿并且标记。表示该岛屿已经被计数过。避免重复计数
                    
                    Dfs(grid,r,c);
                    ++islandNumber;
                    
                }// if(grid[r][c] == '1')
            }
        }//双层for
        return islandNumber;
    }

    private void Dfs(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';
        Dfs(grid,i-1, j);
        Dfs(grid,i+1, j);
        Dfs(grid,i,j-1);
        Dfs(grid,i,j+1);
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值