力扣130. 被围绕的区域

深度优先搜索

  • 思路:
    • 搜索边界上的 'O',并标记染色;
    • 然后循环遍历,将剩余的 'O' 修改为 'X',将标记染色的格子还原成 'O' 即可;
    • 通用岛屿问题搜索连通区域模板:
      • void dfs(std::vector>& board, int r, int c) {
            if (r < 0 || r >= nr_ || c < 0 || c >= nc_ || board[r][c] != 'O') {
                return;
            }
        
            board[r][c] = 'A';
            // up
            dfs(board, r - 1, c);
            // down
            dfs(board, r + 1, c);
            // left
            dfs(board, r, c - 1);
            // right
            dfs(board, r, c + 1);
        }

    • 需要从边界处开始搜索 'O' 的连通区域:
      • // from most left and right column
        for (int r = 0; r < nr_; ++r) {
            dfs(board, r, 0);
            dfs(board, r, nc_ - 1);
        }
        
        // from most up and bottom row
        for (int c = 1; c < nc_ - 1; ++c) {
            dfs(board, 0, c);
            dfs(board, nr_ - 1, c);
        }

      • 需要注意在行边界时,列 c 的遍历范围去除在之前遍历的列边界;
  • 完整代码:
class Solution {
public:
    void solve(vector>& board) {
        nr_ = board.size();
        if (nr_ == 0) {
            return;
        }
        nc_ = board[0].size();

        // from most left and right column
        for (int r = 0; r < nr_; ++r) {
            dfs(board, r, 0);
            dfs(board, r, nc_ - 1);
        }

        // from most up and bottom row
        for (int c = 1; c < nc_ - 1; ++c) {
            dfs(board, 0, c);
            dfs(board, nr_ - 1, c);
        }

        for (int r = 0; r < nr_; ++r) {
            for (int c = 0; c < nc_; ++c) {
                if (board[r][c] == 'A') {
                    board[r][c] = 'O';
                } else if (board[r][c] == 'O') {
                    board[r][c] = 'X';
                }
            }
        }
    }

private:
    void dfs(std::vector>& board, int r, int c) {
        if (r < 0 || r >= nr_ || c < 0 || c >= nc_ || board[r][c] != 'O') {
            return;
        }

        board[r][c] = 'A';
        // up
        dfs(board, r - 1, c);
        // down
        dfs(board, r + 1, c);
        // left
        dfs(board, r, c - 1);
        // right
        dfs(board, r, c + 1);
    }

private:
    int nr_;
    int nc_;
};

你可能感兴趣的:(力扣实践,leetcode,深度优先,算法)