力扣日记1254

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. 后记

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

你可能感兴趣的:(leetcode,算法)