• (图论) 1020. 飞地的数量 ——【Leetcode每日一题】


    ❓ 1020. 飞地的数量

    难度:中等

    给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个 海洋单元格1 表示一个 陆地单元格

    一次 移动 是指从一个陆地单元格走到另一个相邻()的陆地单元格或跨过 grid 的边界。

    返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

    示例 1:

    在这里插入图片描述

    输入:grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
    输出:3
    解释:有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上。

    示例 2:

    在这里插入图片描述

    输入:grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
    输出:0
    解释:所有 1 都在边界上或可以到达边界。

    提示

    • m == grid.length
    • n == grid[i].length
    • 1 <= m, n <= 500
    • grid[i][j] 的值为 01

    💡思路:DFS

    本题要求找到不靠边的陆地面积,那么

    • 我们只要从周边找到陆地
    • 然后 通过 dfs 或者 bfs 将周边靠陆地且相邻的陆地都变成海洋
    • 然后再去重新遍历地图的时候,统计此时还剩下的陆地就可以了。

    🍁代码:(C++、Java)

    C++

    class Solution {
    private:
        int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1}; // 保存四个方向
        int m = 0, n = 0;
        void dfs(int i, int j, vector<vector<int>>& grid){
            if(grid[i][j] == 0){ // 是海洋则返回
                return;
            }
            grid[i][j] = 0;
            for(int k = 0; k < 4; k++){ // 向四个方向遍历
                int nexti = i + dir[k][0];
                int nextj = j + dir[k][1];
                if(nexti < 0 || nexti >= m || nextj < 0 || nextj >= n) continue;
                dfs(nexti, nextj, grid);
            }
        }
    public:
        int numEnclaves(vector<vector<int>>& grid) {
            m = grid.size();
            n = grid[0].size();
            // 从左侧边,和右侧边 向中间遍历
            for(int i = 0; i < m; i++){
                dfs(i, 0, grid);
                dfs(i, n - 1, grid);
            }
            // 从上边和下边 向中间遍历
            for(int i = 0; i < n; i++){
                dfs(0, i, grid);
                dfs(m - 1, i, grid);
            }
            //统计剩余陆地的面积
            int ans = 0;
            for(int i = 0; i < m; i++){
                for(int j = 0; j < n; j++){
                    if(grid[i][j] == 1) ans++;
                }
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    Java

    class Solution {
        private int[][] dir = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}}; // 四个方向
        int m = 0, n = 0;
    
        private void dfs(int i, int j, int[][] grid){
            if(grid[i][j] == 0) return;// 是海洋则返回
            grid[i][j] = 0;
            for(int k = 0; k < 4; k++){// 向四个方向遍历
                int nexti = i + dir[k][0];
                int nextj = j + dir[k][1];
                // 超过边界
                if(nexti < 0 || nexti >= m || nextj < 0 || nextj >= n) continue;
                dfs(nexti, nextj, grid);
            }
        }
        public int numEnclaves(int[][] grid) {
            m = grid.length;
            n = grid[0].length;
            // 从左侧边,和右侧边 向中间遍历
            for(int i = 0; i < m; i++){
                dfs(i, 0, grid);
                dfs(i, n - 1, grid);
            }
            // 从上边和下边 向中间遍历
            for(int j = 0; j < n; j++){
                dfs(0, j, grid);
                dfs(m - 1, j, grid);
            }
            //统计剩余陆地的面积
            int ans = 0;
            for(int i = 0; i < m; i++){
                for(int j = 0; j < n; j++){
                    if(grid[i][j] == 1) ans++;
                }
            }
            return ans;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    🚀 运行结果:

    在这里插入图片描述

    🕔 复杂度分析:
    • 时间复杂度 O ( m n ) O(mn) O(mn),其中mn 分别是网格 grid 的行数和列数。深度优先搜索最多访问每个单元格一次,需要 O ( m n ) O(mn) O(mn) 的时间,遍历网格统计飞地的数量也需要 O ( m n ) O(mn) O(mn) 的时间。

    • 空间复杂度 O ( m n ) O(mn) O(mn),空间复杂度主要取决于递归调用栈空间,最大空间复杂度是 O ( m n ) O(mn) O(mn)

    题目来源:力扣。

    放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
    关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

    注: 如有不足,欢迎指正!
  • 相关阅读:
    notes_jupyter_notebook
    基于 VMware workstation 16 安装 Linux CentOS 8 操作系统(超详细教程)
    【Axure高保真原型】可视化图表图标
    Java Integer reverse(int i)方法具有什么功能呢?
    解析用户消费记录(数据分析三剑客综合使用)
    ISCSLP 2022 | AccentSpeech—从众包数据中学习口音来构建目标说话人的口音语音合成系统
    湘南学院2023级成考新生课程学习安排及成绩评定标准
    Python安装和环境配置教程
    vue源码解读-权衡(性能解决方案)
    毕业设计--基于SSM实现的的校园订餐系统源码+数据库
  • 原文地址:https://blog.csdn.net/weixin_43412762/article/details/132922510