130 Surrounded Regions【思路简化】
class Solution {
public:
bool DFS(vector<vector<char>>& board,vector<vector<int>>& signal,int i , int j){
int m = board.size();
int n = board[0].size();
//区域条件:在区域内、为O、没有探索过
if(i<0 || j<0 || i>m-1 || j >n-1 || board[i][j] == 'X' || signal[i][j] == 1) return false;
//标记
signal[i][j] = 1;
//会出现区域与边缘接壤的情况,这片区域就废了,不能用'X'覆盖
if(i == 0 || i == m-1 || j == 0 || j == n-1) return false;
//up
DFS(board , signal ,i-1 ,j);
//down
DFS(board , signal ,i+1 ,j);
//left
DFS(board , signal ,i ,j-1);
//right
DFS(board , signal ,i ,j+1);
return true;
}
void solve(vector<vector<char>>& board) {
//m*n的matrix,包含X 或 O字符,捕捉被围绕的区域:
//将捕捉区域用'X'进行覆盖
//所以需要明确被捕捉区域:上下左右被X包围,且没有区域在matrix的边缘位置
//判断捕捉条件 & 不能改变board
int m = board.size();
int n = board[0].size();
//用于标记该位置需要被捕捉
vector<vector<int>> signal(m , vector<int>(n,0));
for(int i = 0 ; i < m ; i++){
for(int j = 0 ; j < n ; j++){
if(board[i][j] == 'O'){
//如果返回true,说明不与边缘接壤,就可以进一步标记
//按理来说每个O都能找到所在区域的边缘并判断是否在matrix的边上
//但是,DFS中的过滤条件中包括了 不能标记已经被探索过的区域 否则返回false
//所以如果一个O已经探索完一个区域,再次进入该区域时的O都会别返还FALSE就出错了!!!!
if(DFS(board , signal ,i ,j))signal[i][j] = 2;
}
}
}
//进行捕捉
for(int i = 0 ; i < m ; i++){
for(int j = 0 ; j < n ; j++){
if(signal[i][j] == 2){
board[i][j] = 'X';
}
}
}
}
};
问题分析: 如果返回true,说明不与边缘接壤,就可以进一步标记;按理来说每个O都能找到所在区域的边缘并判断是否在matrix的边上;但是,DFS中的过滤条件中包括了 不能标记已经被探索过的区域 否则返回false;所以如果一个O已经探索完一个区域,再次进入该区域时的O都会别返还FALSE就出错了!!!!
问题解决:solve中不能直接一个个遍历,需要先边缘遍历,将边缘区域都找出来,标记为O X 以外的任意字符,后面直接遍历board将之前标记的字符转化为O,将O转化为X
class Solution {
public:
void DFS(vector<vector<char>>& board,int i , int j){
int m = board.size();
int n = board[0].size();
// 区域条件: 在区域内、为O
if(i < 0 || j < 0 || i >= m || j >= n || board[i][j] != 'O') return;
//标记
board[i][j] = '#';
//up
DFS(board ,i-1 ,j );
//down
DFS(board ,i+1 ,j);
//left
DFS(board ,i ,j-1);
//right
DFS(board ,i ,j+1);
}
void solve(vector<vector<char>>& board) {
//m*n的matrix,包含X 或 O字符,捕捉被围绕的区域:
//将捕捉区域用'X'进行覆盖
//所以需要明确被捕捉区域:上下左右被X包围,且没有区域在matrix的边缘位置
int m = board.size();
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 j = 0 ; j < n ; j++){
if(board[0][j] == 'O'){
DFS(board , 0 , j );
}
if(board[m-1][j] == 'O'){
DFS(board , m-1 , j );
}
}
//剩余区域探索,只要为O变X
//进行捕捉
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] == '#'){
board[i][j] = 'O';
}
}
}
}
};