leet_code_200.岛屿问题(广度与深度)

简介: leet_code_200.岛屿问题(广度与深度)

题目信息


给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:
[
['1','1','1','1','0'],
['1','1','0','1','0'],
['1','1','0','0','0'],
['0','0','0','0','0']
]
输出: 1

示例 2:

输入:
[
['1','1','0','0','0'],
['1','1','0','0','0'],
['0','0','1','0','0'],
['0','0','0','1','1']
]
输出: 3


解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。


代码实现

import java.util.LinkedList;
import java.util.Queue;
public class Test {
    public static void main(String[] args) {
        // 解决岛屿问题
        int[][] land = new int [][]{
                {1,1,0,1,0,0,0,1},
                {0,0,1,0,1,1,1,1},
                {1,1,0,1,1,1,0,0},
                {1,1,0,1,1,1,0,0}
        };
        // System.out.println("深度优先查询:" + getDfsNum(land));
        System.out.println("广度优先查询:" + bfs(land));
    }
    /**
     * 深度优先查询思想:
     * 出现第一个1时,则最少有一个岛屿,然后查其上下左右的值,如果出现为1的,则递归深度查询出所有紧邻的岛屿,出现1,就继续找,不是1,则退出。
     * 遍历到岛屿为1时,将其设为0,因为连着都属于同一个岛屿。故只需在第一个数字上加1.
     * 根据第一个值,一直往下找,直到找到最底层后,然后再处理分支上的数据
     */
    private static int getDfsNum(int[][] grid){
        int landNum = 0;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                if(grid[i][j] == 1){
                    landNum ++;
                    dfs(grid, i, j);
                }
            }
        }
        return landNum;
    }
    private static void dfs(int[][] grid, int i, int j){
        // 如果超出边界或者为0,则直接退出,这里我们只找为1的
        if(i >= grid.length || i < 0 || j >= grid[0].length || j < 0 || grid[i][j] == 0){
            return ;
        }
        // 如果为1,则与上个岛屿连接,均可视为海水,不加数量,故设为0
        grid[i][j] = 0;
        dfs(grid, i - 1, j);
        dfs(grid, i + 1, j);
        dfs(grid, i, j - 1);
        dfs(grid, i, j + 1);
    }
    /**
     * 广度优先搜索思想:
     * 出现第一个1时,则最少有一个岛屿,然后查其上下左右的值,如果出现为1的,则将该位置的数据放入队列中,出现1,就继续找,不是1,则退出。
     * 遍历到岛屿为1时,将其设为0,因为连着都属于同一个岛屿。故只需在第一个数字上加1.
     * 根据第一个值,一层层的往下找,利用队列先进先出的原则,直到该层全部处理完后,再处理下一层。
     */
    private static int bfs(int[][] grid){
        if(grid == null || grid.length == 0){
            return 0;
        }
        int landNum = 0;
        for(int i = 0; i < grid.length; i ++){
            for (int j = 0; j < grid[i].length; j++) {
                if(grid[i][j] == 1){
                    // 出现第一个岛屿,岛屿数直接+1
                    landNum ++;
                    // 已加完数量,将岛屿设为0,与海水混为一谈
                    grid[i][j] = 0;
                    Queue<Integer> queue = new LinkedList<>();
                    queue.add(i * grid[0].length + j);
                    // 队列不为空,则一直处理下去
                    while(!queue.isEmpty()){
                        // 遍历到当前,没有价值,删掉当前值
                        int id = queue.remove();
                        // 除数求第几行
                        int row = id / grid[0].length;
                        // 余数求第几列
                        int col = id % grid[0].length;
                        // 如果为1,则与上个岛屿连接,均可视为海水,不加数量,故设为0
                        // 上
                        if(row - 1 >= 0 && grid[row - 1][col] == 1){
                            grid[row-1][col] = 0;
                            queue.offer((row - 1) * grid[0].length + col);
                        }
                        // 下
                        if(row + 1 < grid.length && grid[row + 1][col] == 1){
                            grid[row+1][col] = 0;
                            queue.offer((row + 1) * grid[0].length + col);
                        }
                        // 左
                        if(col - 1 > 0 && grid[row][col - 1] == 1){
                            grid[row][col-1] = 0;
                            queue.offer(row * grid[0].length + (col - 1));
                        }
                        // 右
                        if(col + 1 < grid[0].length && grid[row][col + 1] == 1){
                            grid[row][col+1] = 0;
                            queue.offer(row * grid[0].length + (col + 1));
                        }
                    }
                }
            }
        }
        return landNum;
    }
}


目录
相关文章
|
6月前
|
算法
【经典LeetCode算法题目专栏分类】【第4期】BFS广度优先算法:单词接龙、最小基因变化、二进制矩阵中的最短路径
【经典LeetCode算法题目专栏分类】【第4期】BFS广度优先算法:单词接龙、最小基因变化、二进制矩阵中的最短路径
|
7月前
每日一题来噜!(记负均正,旋转数组中的最小数字)
每日一题来噜!(记负均正,旋转数组中的最小数字)
34 1
|
算法
【算法挨揍日记】day03——双指针算法_有效三角形的个数、和为s的两个数字
【算法挨揍日记】day03——双指针算法_有效三角形的个数、和为s的两个数字
53 0
|
算法
LeetCode每日一题--二叉树的最小深度
LeetCode每日一题--二叉树的最小深度
127 0
leet_code_111.二叉树最小深度(深度、广度)
leet_code_111.二叉树最小深度(深度、广度)
67 0
|
索引
【day04】力扣(LeetCode)每日一刷[1306. 跳跃游戏 III ][703. 数据流中的第 K 大元素 ][1337. 矩阵中战斗力最弱的 K 行]
了解学习 跳跃游戏 III , 数据流中的第 K 大元素 , 矩阵中战斗力最弱的 K 行。
210 0
【day04】力扣(LeetCode)每日一刷[1306. 跳跃游戏 III ][703. 数据流中的第 K 大元素 ][1337. 矩阵中战斗力最弱的 K 行]
|
算法 机器人 PHP
力扣(LeetCode)算法题解:657. 机器人能否返回原点
力扣(LeetCode)算法题解:657. 机器人能否返回原点
127 0
|
存储 人工智能 Java
LeetCode每日一题-8:重塑矩阵
LeetCode每日一题-8:重塑矩阵