leetcode 130. 被围绕的区域
问题描述
给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。
找到所有被 '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'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
代码
class Solution {
public:
void solve(vector<vector<char>>& board) {
int m = board.size();
if(m < 1)return;
int i,j,n = board[0].size();
for(i = 0; i < m; ++i)
{
if(board[i][0] == 'O')//把最左边与'O'连通的变为'#'
dfs(i,0,m,n,board);
if(board[i][n-1] == 'O')//把最右边与'O'连通的变为'#'
dfs(i,n-1,m,n,board);
}
for(j = 0; j < n; ++j)
{
if(board[0][j] == 'O')//把最上边与'O'连通的变为'#'
dfs(0,j,m,n,board);
//cout<<board[m-1][j]<<" ";
if(board[m-1][j] == 'O')//把最下边与'O'连通的变为'#'
dfs(m-1,j,m,n,board);
}
//剩下的'O'都不与边界相连可以变为'X','#'重新变为'O'
for(i = 0; i < m; ++i)
{
for(j = 0; j < n; ++j)
{
if(board[i][j] == 'O')board[i][j] = 'X';
else if(board[i][j] == '#')board[i][j] = 'O';
}
}
}
void dfs(int i,int j,int& m,int& n,vector<vector<char>>& board)
{
if(i < 0 || j < 0 || i >= m || j >= n || board[i][j]!='O')
return;
board[i][j] = '#';
if(i-1>0 && board[i-1][j]=='O')
dfs(i-1,j,m,n,board);
if(i+1<m && board[i+1][j]=='O')
dfs(i+1,j,m,n,board);
if(j-1>0 && board[i][j-1]=='O')
dfs(i,j-1,m,n,board);
if(j+1<n && board[i][j+1]=='O')
dfs(i,j+1,m,n,board);
}
};
结果
执行用时 :24 ms, 在所有 C++ 提交中击败了99.66%的用户
内存消耗 :10.1 MB, 在所有 C++ 提交中击败了100.00%的用户
代码2(循环)
class Solution {
public:
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
void solve(vector<vector<char>>& board) {
int m = board.size();
if(m < 1)return;
int i,j,n = board[0].size();
for(i = 0; i < m; ++i)
{
if(board[i][0] == 'O')
bfs(i,0,m,n,board);
if(board[i][n-1] == 'O')
bfs(i,n-1,m,n,board);
}
for(j = 0; j < n; ++j)
{
if(board[0][j] == 'O')
bfs(0,j,m,n,board);
if(board[m-1][j] == 'O')
bfs(m-1,j,m,n,board);
}
//剩下的'O'都不与边界相连可以变为'X','#'重新变为'O'
for(i = 0; i < m; ++i)
{
for(j = 0; j < n; ++j)
{
if(board[i][j] == 'O')board[i][j] = 'X';
else if(board[i][j] == '#')board[i][j] = 'O';
}
}
}
void bfs(int i,int j,int& m,int& n,vector<vector<char>>& board)
{
queue<int> q;
board[i][j] = '#';
q.push(i*n+j);//注意是乘n
while(!q.empty())
{
int ind = q.front();
q.pop();
int indx = ind/n,indy = ind%n;
for(int k = 0; k < 4; ++k)
{
int ii = indx + dir[k][0];
int jj = indy + dir[k][1];
if(ii > 0 && ii < m && jj > 0 && jj < n && board[ii][jj] == 'O')
{
board[ii][jj] = '#';
q.push(ii*n+jj);
}
}
}
}
};
结果
执行用时 :36 ms, 在所有 C++ 提交中击败了77.31%的用户
内存消耗 :11 MB, 在所有 C++ 提交中击败了100.00%的用户