LeetCode 1020.飞地的数量(dfs)

题目传送门: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] 的值为 0 或 1

题目分析:

注意一下是m行n列的矩阵,不要想当然的认为是m行m列的矩阵(虽然代码差不多),然后就是基础的dfs了。题目所要求的是返回网格中无法在任意次数的移动中离开网格边界的陆地单元格的数量,因为在每一个陆地单元中只能 上、下、左、右 移动,因此只要矩阵中的 1 (陆地)和矩阵边界四个方向相邻的元素都为0(海洋),此时内部所有陆地单元格都无法离开网格边界,然后再返回 1 (陆地单元格)的个数即可。

拿示例二的图来简单分析一下:

                  

我们用dfs来搜索和边界中的陆地相邻的陆地。边界(即 深蓝色0 )为我们所要dfs开始搜索的范围,当我们在边界中找到陆地(淡蓝色1)时再不断向内搜索直到可搜索的陆地单元格最大,然后再将其置0,因为我们不需要求这些陆地单元格的个数。最后再遍历整个矩阵返回矩阵中 剩余 1的个数。

代码(c++):

class Solution {
public:
    int numEnclaves(vector<vector<int>>& grid) {
        int row=grid.size(),col=grid[0].size();
        for(int i=0;i<row;i++)
        {
            dfs(grid,i,0);//第一列
            dfs(grid,i,col-1);//最后一列
        }
        for(int j=0;j<col;j++)
        {
            dfs(grid,0,j);//第一行
            dfs(grid,row-1,j);//最后一行
        }
        int count=0;
        for(int i=0;i<row;i++)
        {
            for(int j=0;j<col;j++)
            {
                if(grid[i][j]==1)
                    count++;
            }
        }
        return count;
    }
    void dfs(vector<vector<int>>& grid,int row,int col){
        if(row<0 || row>grid.size()-1 || col<0 || col>grid[0].size()-1 || grid[row][col]==0)
            return;
        grid[row][col]=0;//如果和外界相连则变为0
        dfs(grid,row-1,col);//上
        dfs(grid,row+1,col);//下
        dfs(grid,row,col-1);//左
        dfs(grid,row,col+1);//右
    }
};

计算机204 zjr

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值