力扣日记1254

文章介绍了LeetCode1254题目的解法,主要通过BFS广度优先搜索策略来找出并计数被1包围的0的区域。在遍历过程中,遇到0则开始搜索,并标记已访问,同时处理边界条件。时间复杂度为O(mn),空间复杂度也为O(mn)。作者分享了自己的代码实现,并提到一种优化思路,即先处理边界上的0。最后,作者表示代码一次性调试正确。

1. 题目

LeetCode 1254. 统计封闭岛屿的数目

1.1 题意

找出被1围住的0的区域的数量

1.2 分析

1 <= grid.length, grid[0].length <= 100
0 <= grid[i][j] <=1

这个题要搜索为0的区域,遍历每个位置,如果该位置为0,那么就由这个点开始做bfs广度优先搜索,然后访问过的0的位置需要打个标记已经访问,可以直接在数组原地打标记,让后不会在访问访问过的点。
在开始bfs前需要使用一个标记,来记录bfs过程是否遇到了边界,如果遇到了边界,就不是合法的情况。

1.3 我的解法

class Solution {
public:
    int closedIsland(vector<vector<int>>& grid) {
        int res=0;
        int index = 1;
        int n = grid.size(), m = grid[0].size();
        // 四个方向
        vector<int> x_bias{1,0,-1,0};
        vector<int> y_bias{0,1,0,-1};

        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                // 该位置是未遍历的陆地
                if(grid[i][j] == 0){
                    index ++ ; // 用不同的下标标记不同的联通陆地区域
                    int changeFlag = 1; // 标记是否没有遇到边界
                    if(i == 0 || i == n-1 || j == 0 || j == m-1){
                        // 无效陆地区域
                        changeFlag = 0;
                    }
                    // bfs
                    queue<pair<int, int> > q;
                    q.push(make_pair(i,j) );
                    while(!q.empty()){
                        int x = q.front().first;
                        int y = q.front().second;
                        q.pop();
                        // 标记该块陆地已经访问过
                        grid[x][y] = index;
                        // 向四个方向搜索
                        for(int k=0;k<4;k++){
                            int dx = x + x_bias[k];
                            int dy = y + y_bias[k];
                            if(dx >=0 && dx < n && dy >= 0 && dy < m){
                                // 判断是否合法位置
                                if(grid[dx][dy] == 1){
                                    // 搜到海洋直接结束
                                    continue;
                                }
                                else if(grid[dx][dy] == 0){
                                    // 搜到陆地继续搜索
                                    q.push(make_pair(dx, dy) );
                                }
                                if(dx == 0 || dx == n-1 || dy == 0 || dy == m-1){
                                    // 搜到边界
                                    // 无效陆地区域
                                    changeFlag = 0;
                                }
                            }
                        }
                    }
                    if(changeFlag){
                        // 如果没有靠到边界
                        // 为需要计算到的陆地区域数
                        res++;
                    }
                }
            }
        }
            
        return res;
    }
};

1.4 学习题解反思

时间复杂度O(mn), 空间复杂度O(mn)(最坏情况需要记录所有的点)

题解中看到一个有意思的解法,先把边界的0通过搜索变成1,在进行bfs,这样可以不用使用标记来记录。

1.5 bug日记

居然调对了

2. 后记

仅分享自己的想法,有意见和指点非常感谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值