day67—DFS—被围绕的区域(LeetCode-130)
题目描述
给你一个 m x n
的矩阵 board
,由若干字符 'X'
和 'O'
组成,捕获 所有 被围绕的区域:
- 连接:一个单元格与水平或垂直方向上相邻的单元格连接。
- 区域:连接所有
'O'
的单元格来形成一个区域。 - 围绕:如果您可以用
'X'
单元格 连接这个区域,并且区域中没有任何单元格位于board
边缘,则该区域被'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"]]
解释:
在上图中,底部的区域没有被捕获,因为它在 board 的边缘并且不能被围绕。
示例 2:
输入:board = [["X"]]
输出:[["X"]]
提示:
m == board.length
n == board[i].length
1 <= m, n <= 200
board[i][j]
为'X'
或'O'
解决方案:
1、边缘单独标注,即 从边界开始向内搜索
2、全局遍历,把内部的空直接填充即可
3、恢复边缘块的符号
函数源码:
class Solution { public:void solve(vector<vector<char>>& board) {int m=board.size();if(m==0) return;int n=board[0].size();//第一步:左,右for(int i=0;i<m;i++){if(board[i][0] == 'O' ) dfs(board,i,0);if(board[i][n-1] == 'O' )dfs(board,i,n-1);}//上,下for(int i=0;i<n;i++){if(board[0][i] == 'O' ) dfs(board,0,i);if(board[m-1][i] == 'O' )dfs(board,m-1,i);} //第二步:for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(board[i][j]=='O') board[i][j]='X';if(board[i][j]=='b') board[i][j]='O';}}}//(x,y):左,下,右,上————即:逆时针vector<int> direction{-1,0,1,0,-1};void dfs(vector<vector<char>>& board,int x,int y){board[x][y]='b';for(int i=0;i<4;i++){int dx=x+direction[i];int dy=y+direction[i+1];//越界条件(x,y)if( dx<0 || dx>=board.size() || dy<0 || dy>=board[0].size() ) continue;if(board[dx][dy] == 'X' || board[dx][dy] == 'b') continue;dfs(board,dx,dy);}return;}};