LeetCode 1020 飞地的数量

题目链接:LeetCode 1020 飞地的数量

题目大意:

题解:
很显然,边缘的\(1\)或者与边缘的\(1\)直接或间接相连的\(1\)可以离开网格边界。
从外向内搜索与边缘的\(1\)直接或间接相连的\(1\),并打上标记,再遍历数组统计未打上标记的\(1\)的个数。

class Solution {
private:
    vector<vector<int>> dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

public:
    int numEnclaves(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<bool>> vis(n, vector<bool>(m, false));
        queue<pair<int, int>> q;
        for (int i = 0; i < m; ++i) {
            if (grid[0][i]) {
                vis[0][i] = true;
                q.emplace(0, i);
            }
            if (grid[n - 1][i]) {
                vis[n - 1][i] = true;
                q.emplace(n - 1, i);
            }
        }
        for (int i = 1; i < n - 1; ++i) {
            if (grid[i][0]) {
                vis[i][0] = true;
                q.emplace(i, 0);
            }
            if (grid[i][m - 1]) {
                vis[i][m - 1] = true;
                q.emplace(i, m - 1);
            }
        }
        while (!q.empty()) {
            auto& [x, y] = q.front();
            for (auto& dir : dirs) {
                int nx = x + dir[0], ny = y + dir[1];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] && !vis[nx][ny]) {
                    vis[nx][ny] = true;
                    q.emplace(nx, ny);
                }
            }
            q.pop();
        }
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (grid[i][j] && !vis[i][j]) {
                    ans++;
                }
            }
        }
        return ans;
    }
};
posted @ 2022-02-12 19:12  ZZHHOOUU  阅读(26)  评论(0编辑  收藏  举报