洪水填充

[Algo] 洪水填充

1. 被围绕的区域

// 1. 被围绕的区域
// https://leetcode.cn/problems/surrounded-regions/description/
void dfs1(vector<vector<char>>& board, int i, int j)
{
    int n = board.size();
    int m = board[0].size();
    if (i < 0 || j < 0 || i >= n || j >= m || board[i][j] != 'O') return;
    board[i][j] = 'F';
    dfs1(board, i - 1, j);
    dfs1(board, i + 1, j);
    dfs1(board, i, j - 1);
    dfs1(board, i, j + 1);
}
void solve(vector<vector<char>>& board) {
    int n = board.size();
    int m = board[0].size();
    for (int j = 0; j < m; j++) dfs1(board, 0, j);
    for (int j = 0; j < m; j++) dfs1(board, n - 1, j);
    for (int i = 1; i < n - 1; i++) dfs1(board, i, 0);
    for (int i = 1; i < n - 1; i++) dfs1(board, i, m - 1);
    for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
    {
        if (board[i][j] == 'F') board[i][j] = 'O';
        else if (board[i][j] == 'O') board[i][j] = 'X';
    }
}

2. 最大人工岛

// 2. 最大人工岛
// https://leetcode.cn/problems/making-a-large-island/
void dfs2(vector<vector<int>>& grid, int i, int j, int cnt)
{   
    int n = grid.size();
    int m = grid[0].size();
    if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) return;
    grid[i][j] = cnt;
    dfs2(grid, i - 1, j, cnt);
    dfs2(grid, i + 1, j, cnt);
    dfs2(grid, i, j - 1, cnt);
    dfs2(grid, i, j + 1, cnt);
}
int largestIsland(vector<vector<int>>& grid) {
    int n = grid.size();
    int m = grid[0].size();
    int cnt = 1;
    for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
    {
        if (grid[i][j] == 1) dfs2(grid, i, j, ++cnt);
    }
    unordered_map<int, int> island;
    bool all_one = true;
    for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
    {
        if (grid[i][j] != 0) island[grid[i][j]]++;
        else all_one = false;
    }
    if (all_one) return n * m;
    int ans = 0;
    for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
    if (grid[i][j] == 0)
    {
        set<int> s;
        int cur = 1;
        if (i != 0 && grid[i - 1][j] != 0) s.insert(grid[i - 1][j]);
        if (j != 0 && grid[i][j - 1] != 0) s.insert(grid[i][j - 1]);
        if (i != n - 1 && grid[i + 1][j] != 0) s.insert(grid[i + 1][j]);
        if (j != m - 1 && grid[i][j + 1] != 0) s.insert(grid[i][j + 1]);
        for (auto index : s) cur += island[index];
        ans = max(ans, cur);
    }
    return ans;
}

3. 打砖块

// 3. 打砖块
// https://leetcode.cn/problems/bricks-falling-when-hit/
int cnt = 0;
int get(vector<vector<int>>& grid, int i, int j)
{
    int n = grid.size();
    int m = grid[0].size();
    if (i < 0 || j < 0 || i >= n || j >= m) return -1;
    return grid[i][j];
}
void dfs3(vector<vector<int>>& grid, int i, int j)
{   
    int n = grid.size();
    int m = grid[0].size();
    if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) return;
    grid[i][j] = 2;
    cnt++;
    dfs3(grid, i - 1, j);
    dfs3(grid, i + 1, j);
    dfs3(grid, i, j - 1);
    dfs3(grid, i, j + 1);
}
vector<int> hitBricks(vector<vector<int>>& grid, vector<vector<int>>& hits) {
    vector<int> ans;
    for (int i = 0; i < hits.size(); i++) grid[hits[i][0]][hits[i][1]]--;
    for (int j = 0; j < grid[0].size(); j++) dfs3(grid, 0, j);
    for (int i = hits.size() - 1; i >= 0; i--)
    if (++grid[hits[i][0]][hits[i][1]] == 1)
    {
        // 两种情况需要进行洪水填充: 1. 与顶部相连 2. 与其他已经填充的砖块相连
        if (hits[i][0] == 0 || get(grid, hits[i][0] - 1, hits[i][1]) == 2 
                            || get(grid, hits[i][0] + 1, hits[i][1]) == 2
                            || get(grid, hits[i][0], hits[i][1] + 1) == 2
                            || get(grid, hits[i][0], hits[i][1] - 1) == 2)
        {
            cnt = 0;
            dfs3(grid, hits[i][0], hits[i][1]);
            ans.push_back(cnt - 1);
        }
        else ans.push_back(0);
    }
    else ans.push_back(0);
    reverse(ans.begin(), ans.end());
    return ans;
}
posted @ 2025-01-06 09:33  yaoguyuan  阅读(14)  评论(0)    收藏  举报