给出一个包含'X'和'O'的2D板,捕获所有'X'围绕的区域。

一个区域被捕获是指翻转被围绕区域中的所有'O'为'X'。

例如,

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围绕,其实就是看从该点出发有没有一条路径能走到二维数组的区域外。在程序语言中,向上下左右移动分别为:[i-1, j], [i+1, j], [i, j-1], [i, j+1]。而找路径的步骤就是从O点出发向附近的O点不断移动的过程。要实现“不断移动”,一种方案是使用递归调用。由于极端情况下四个方向都能移动,在矩阵较大的时候可以想象递归调用栈的层数将会很多。而另一种比较直观的方案就是不断重复扫描二维数组,做出移动的动作,直到没有点可以移动为止。这种方案看起来比较直观,但是还需要解决几个问题:

1. 如果在移动过程中有走到边界的情况,即表示改点没有被围绕。要怎么要判断边界点?

可以通过i-1 < 0, i + 1 >= board.size(), j - 1 < 0, j + 1 >= board[0].size()这四个条件,只要某点坐标符合其中一个条件,它就是在边界上的点。

2. 由于四个方向移动,如何判断已走过的点?

由于我们只向O点移动,可以在移动到某点后将该点的值修改,如改为'P'。每次扫描都以P点作为移动的起点。最后根据是否找到路径的情况将P改为X或O。

3. 如何判断没有点可以移动?

很简单,我们可以在每次扫描前将一个标志设为false。在该次扫描中只要有过移动,将其置为true。扫描完后根据该变量值决定是否继续即可。

4. 如何找P点?

一次二重循环肯定是不够的,因为二重循环是不断地向右下移动。而P点可以向左或向上移动。这里我们先采用一个最简单的方案,不断地从最左上角即[0,0]开始找P,直到没有P点可以移动。这样一定可以保证不会有漏掉的P点。但可以看到将会有一个三重循环。

好了,看起来解决方案已经有了,让我们模拟一下:

遍历至[1,1],发现O点,将其置为P。开始扫描

                 [1,1]发现P  [1,2]发现P   [2,2]发现P                          没有路径,将P替换成X

                 只能向右     只能向下      无路可走,没有路径,返回

X X X X      X X X X      X X X X      X X X X                             X X X X

X P O X      X P P X       X P P X       X P P X                              X X X X

X X O X      X X O X      X X P X      X X P X                              X X X X

X O X X      X O X X      X O X X     X O X X                              X O X X

遍历至[3,1],发现O点,将其置为P。开始扫描

                 [3, 1]发现P                    有路径,将P替换回O

                 无路可走,有路径

X X X X      X X X X                         X X X X

X X X X      X X X X                         X X X X

X X X X      X X X X                         X X X X

X P X X      X P X X                          X O X X

看来的确能得出例子中的答案。好了,那么开始写代码吧:

  1 class Solution
  2 {
  3 public:
  4     void solve(std::vector<std::vector<char>> &board)
  5     {     
  6         for(int i = 0; i < board.size(); ++i)
  7         {
  8             for(int j = 0; j < board[i].size(); ++j)
  9             {
 10                 if(board[i][j] == 'O')
 11                 {
 12                     if(!FindPath(board, i, j))
 13                     {
 14                         ReplaceBack(board, SURROUNDED);
 15                     }
 16                     else
 17                     {
 18                         ReplaceBack(board, NOT_SURROUNDED);
 19                     }
 20                 }
 21             }
 22         }    
 23     }
 24 private:
 25     enum ReplaceMethod
 26     {
 27         SURROUNDED,
 28         NOT_SURROUNDED
 29     };
 30 
 31     void ReplaceBack(std::vector<std::vector<char>> &board, ReplaceMethod replaceMethod)
 32     {
 33         for(int i = 0; i < board.size(); ++i)
 34         {
 35             for(int j = 0; j < board[i].size(); ++j)
 36             {
 37                 if(board[i][j] == 'P')
 38                 {
 39                     if(replaceMethod == SURROUNDED)
 40                     {
 41                         board[i][j] = 'X';
 42                     }
 43                     else
 44                     {
 45                         board[i][j] = 'O';
 46                     }
 47                 }
 48             }
 49         }
 50     }
 51 
 52 bool FindPath(std::vector<std::vector<char>> &board, int X, int Y)
 53     {
 54         board[X][Y] = 'P';
 55         
 56         bool hasPath = false;
 57         bool canMove = false;
 58         
 59         while(true)
 60         {
 61             canMove = false;
 62             for(int i = 0; i < board.size(); ++i)
 63             {
 64                 for(int j = 0; j < board[i].size(); ++j)
 65                 {
 66                     if(board[i][j] == 'P')
 67                     {
 68                         if(i - 1 < 0)
 69                         {
 70                             hasPath = true;
 71                         }
 72                         else
 73                         {
 74                             if(board[i-1][j] == 'O')
 75                             {
 76                                 board[i-1][j] = 'P';
 77                                 canMove = true;
 78 
 79                             }
 80                         }
 81                         
 82                         if(j - 1 < 0)
 83                         {
 84                             hasPath = true;
 85                         }
 86                         else
 87                         {
 88                             if(board[i][j - 1] == 'O')
 89                             {
 90                                 board[i][j - 1] = 'P';
 91                                 canMove = true;
 92                                 
 93 
 94                             }
 95                         }
 96                         
 97                         if(i + 1 >= board.size())
 98                         {
 99                             hasPath = true;
100                         }
101                         else
102                         {
103                             if(board[i+1][j] == 'O')
104                             {
105                                 board[i+1][j] = 'P';
106                                 canMove = true;
107                             }
108                         }
109                         
110                         if(j + 1 >= board[0].size())
111                         {
112                             hasPath = true;
113                         }
114                         else
115                         {
116                             if(board[i][j + 1] == 'O')
117                             {
118                                 board[i][j + 1] = 'P';
119                                 canMove = true;
120                             }
121                         }                    
122                     }                
123                 }            
124             }
125             if(!canMove)
126             {
127                 return hasPath;
128             }
129         }
130         return hasPath;
131     }
132 
133 };
View Code

相关文章:

  • 2021-08-29
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-03-03
  • 2021-09-30
  • 2021-06-02
猜你喜欢
  • 2021-11-11
  • 2021-09-12
  • 2022-12-23
  • 2021-07-28
  • 2021-11-12
  • 2021-10-09
  • 2021-05-18
相关资源
相似解决方案