1、描述
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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/surrounded-regions
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2、关键字
二维矩阵、连通到边,和在内部
3、思路
bfs,并查集(目前还不熟)
4、notes
1、BFS这个题一层是外圈的一层,向内圈卷,
2、bfs的第3步中内层循环时,变ke成了 队列元素向4个方向搜索,
3、陆地填海的方向方式,用一维数组{0,1,0,-1,0}完成方向初始化
4、pair<int,int>结构,在queue中可以直接用que.emplace(1,2),来添加值,下面等价
que.emplace(i,0);
que.push({i,0});
5、复杂度
时间:O(n*M),行数和列数,最多遍历一次,
空间:O(n×m),其中 n 和 m 分别为矩阵的行数和列数。主要为广度优先搜索的队列的开销。
6、code
class Solution {
public:
const int direct[5]={0,1,0,-1,0}; //方向
void solve(vector<vector<char>>& board) {
int n=board.size();
if(n==0) return;
int m=board[0].size();
//const int direct[5]={0,1,0,-1,0}; //方向写这里也能行
queue<pair<int,int>>que;
//int i,j;
for(int i=0;i<n;i++){ // 初始化que队列,
if(board[i][0]=='O') // 遍历第一列
{
que.emplace(i,0);
//board[i][0]='A'; //从这里开始修改也行,不过放到从队列里删除的时候再修改也行
}
if(board[i][m-1]=='O') // 遍历最后一列
{
que.emplace(i,m-1);
//board[i][m-1]='A';
}
}
for(int i=1;i<m-1;i++){ // 此处写成 ;i<m; 也能行
if(board[0][i]=='O') // 遍历第一行
{
que.emplace(0,i);
//board[0][i]='A';
}
if(board[n-1][i]=='O') // 遍历最后一行
{
que.emplace(n-1,i);
//board[n-1][i]='A';
}
}
while(!que.empty()) // 2、外层循环
{
//int longth=que.size();
//while(longth--){ // 不必这样内层循环,内层循环变成了当前节点的4个方向
auto tem=que.front(); // 一样获取队首元
que.pop(); // 一样删除队首元
int x=tem.first;
int y=tem.second;
board[x][y]='A'; // 此处一起修改当前的元素
for(int i=0;i<4;i++) // 3 、内层循环
{
int nx=x+direct[i];
int ny=y+direct[i+1];
if(nx<0||nx>=n || ny<0 || ny>=m || board[nx][ny]!='O')
continue;
que.emplace(nx,ny);
//board[nx][ny]='A'; // 此处写了也不错,不过也可以不写,在从队列中删除的时候一起修改就行了
}
//}
}
for(int i=0;i<n;i++) // 遍历整个board,相应修改
{
for(int j=0;j<m;j++)
{
if(board[i][j]=='O')
board[i][j]='X';
if(board[i][j]=='A')
board[i][j]='O';
}
}
}
};