算法学习笔记(九):网格图DFS、图论算法DFS、动态规划DP、贪心

一.网格图DFS

适用于需要计算连通块个数、大小的题目

1.岛屿数量

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

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

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

        

     

class Solution {
    public int numIslands(char[][] grid) {
        /**
            插旗法:
            真他妈牛逼,看了下题解真不是人想出来的
            也就是说从起点开始,从四个方向开始遍历,直到发现边界就停止
            边界:为0,或者到头了,或者已经被插旗
            这样只要是起点能连通的位置都会被插旗,剩下的就是隔着0的区域访问不到
            那么就相当于当前这一大块就是一个岛屿
            然后继续寻找下一个岛屿
         */
        int count = 0;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                //从[0,0]开始作为起点进行插旗
                if (grid[i][j] == '1') {
                    dfs(i, j, grid);
                    count++;
                }
            }
        }
        return count;
    }

    private void dfs(int i, int j, char[][] grid) {
        //边界问题
        if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length 
                || grid[i][j] != '1') {
            return;
        }
        //重点:将当前节点插旗,变为不为1的数
        grid[i][j] = '0';
        //开始四个方向进行dfs
        //上
        dfs(i - 1, j, grid);
        //下
        dfs(i + 1, j, grid);
        //左
        dfs(i, j - 1, grid);
        //右
        dfs(i, j + 1, grid);
    }    
}

2.岛屿的最大面积

        给你一个大小为 m x n 的二进制矩阵 grid

        岛屿是由一些相邻的 1(土地)构成的组合,这里的相邻要求两个1必须在水平或者竖直的四个

        方向上相邻,你可以假设grid的四个边缘都被0(水)包围

        岛屿的面积是岛上值为1的单元格的数目

        请计算grid的最大岛屿面积,如果没有岛屿,请返回0     

class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        //插旗法 比上一题难一点 要算面积
        int sum = 0;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                if (grid[i][j] == 1) {
                    sum = Math.max(sum, dfs(i, j, grid));
                }
            }
        }
        return sum;
    }

    private int dfs(int i, int j, int[][] grid) {
        //边界问题一订要定义好 不然会越界
        if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != 1) {
            return 0;
        }
        int sum = 0;
        grid[i][j] = 2;
        sum++;  //自身
        sum += dfs(i - 1, j, grid); //上
        sum += dfs(i + 1, j, grid); //下
        sum += dfs(i, j - 1, grid); //左
        sum += dfs(i, j
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值