130. 被围绕的区域(多源BFS)

130. 被围绕的区域

给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

 

示例 1:

输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

示例 2:

输入:board = [["X"]]
输出:[["X"]]

 

提示:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 200
  • board[i][j] 为 'X' 或 'O'
 1 class Solution {
 2 public:
 3     static constexpr int g_directions[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
 4     // 判定是否越界
 5     bool isInArea(int x, int y) {
 6         return (x >= 0 && x < row && y >= 0 && y < col);
 7     }
 8     // 将边界'O'入队并设置为已访问
 9     void addEdgeToQueue(vector<vector<char>> &board, vector<vector<bool>> &visited, 
10         queue<std::pair<int, int>> &q) {
11         for (int i = 0; i < row; i++) {
12             if (board[i][0] == 'O') {
13                 q.push({i, 0});
14                 visited[i][0] = true;
15             }
16             if (board[i][col - 1] == 'O') {
17                 q.push({i, col - 1});
18                 visited[i][col - 1] = true;
19             }
20         }
21         for (int j = 1; j < col - 1; j++) {
22             if (board[0][j] == 'O') {
23                 q.push({0, j});
24                 visited[0][j] = true;
25             }
26             if (board[row - 1][j] == 'O') {
27                 q.push({row - 1, j});
28                 visited[row - 1][j] = true;
29             }
30         }        
31     }
32     // 将与边界连通的'O'方格标记为已访问
33     void bfs(vector<vector<char>> &board, vector<vector<bool>> &visited, queue<std::pair<int, int>> &q) {
34         while (!q.empty()) {
35             int size = q.size();
36             for (int i = 0; i < size; i++) {
37                 auto [curX, curY] = q.front();
38                 q.pop();
39                 for (auto &direction : g_directions) {
40                     int nextX = direction[0] + curX;
41                     int nextY = direction[1] + curY;
42                     if (!isInArea(nextX, nextY) || visited[nextX][nextY]) {
43                         continue;
44                     }
45                     if (board[nextX][nextY] == 'O') {
46                         q.push({nextX, nextY});
47                         visited[nextX][nextY] = true;
48                     }
49                 } 
50             }
51         }
52     }
53     void solve(vector<vector<char>>& board) {
54         row = board.size();
55         col = board[0].size();
56         queue<std::pair<int, int>> q;
57         vector<vector<bool>> visited(row, vector<bool>(col, false));
58         // 将边界'O'坐标入队
59         addEdgeToQueue(board, visited, q);
60         // 将与边界'O'相连的'O'标记为已访问
61         bfs(board, visited, q);
62         // 遍历非边界矩阵元素,将未访问的'O'修改成'X'
63         for (int i = 1; i < row - 1; i++) {
64             for (int j = 1; j < col - 1; j++) {
65                 if (board[i][j] == 'O' && !visited[i][j]) {
66                     board[i][j] = 'X';
67                 }
68             }
69         }
70     }
71 private:
72     int row;
73     int col;
74 };

 

posted @ 2022-06-25 21:47  跳动的休止符  阅读(38)  评论(0)    收藏  举报