[路飞]_1020.飞地的数量

583 阅读2分钟

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战

1020. 飞地的数量

题目

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

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

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

示例1

image.png

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

示例2

image.png

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

题解

DFS

  • 题目要求统计无法在任意次数的移动中离开网格边界的陆地单元格的数量
  • 反过来想,是不是有一些陆地是可以移动到网格边界的

理解了上面的两句话解题就比较简单的了

因为陆地单元格可以想上下左右4个方向移动,所以可以以网格边界上的路径为起点,如果是陆地网格,开始DFS向上下左右4个方向搜索网格,如果存在陆地网格,根据陆地网格的位置继续向上下左右4个方向搜索,直到上下左右4个方向网格都是非陆地,结束搜索;

在搜索过程中将路径上陆地网格修改为非陆地网格;

统计二维数组中剩余陆地网格即可

根据上述思路编辑代码如下:

var numEnclaves = function(grid) {
    const m = grid.length;
    const n = grid[0].length;
    const row = [0,0,-1,1]
    const col = [1,-1,0,0]

    // 上下边界
    for(let i = 0 ; i < n ; i++){
        // 上边界
        if(grid[0][i] === 1){
            dfs(0,i)
        }
        // 下边界
        if(grid[m-1][i] === 1){
            dfs(m-1,i)
        }

    }


    // 左右边界

    for(let i = 0 ; i < m ; i++){
        if(grid[i][0] === 1){
            dfs(i,0)
        }
        if(grid[i][n-1] === 1){
            dfs(i,n-1)
        }
    }


    let result = 0;
    for(let i = 0 ; i < m ; i++){
        for(let j = 0 ; j < n ; j++){
            if(grid[i][j] === 1) result++;
        }
    }
    return result


    
    function dfs(i,j){
        grid[i][j] = '-';
        for(let k = 0 ; k < 4 ; k++){
            const x = row[k] + i;
            const y = col[k] + j;
            if(x >=0 && x < m && y >=0 && y < n && grid[x][y] === 1){
                dfs(x,y)
            }
        }
    }

};