Leetcode题解系列——130. Surrounded Regions(c++版)

版权声明: https://blog.csdn.net/dickdick111/article/details/82990550

题目链接:130. Surrounded Regions

题目大意:给出一个二维的图,由X和O两种字符构成。现在想要将符合条件的O变成X,条件为被X所包围,且没有连接的O处在四个边沿上。

注意点:

  1. 注意判断搜索时,会出现越界情况
  2. 当传入图为空的处理情况
  3. visited数组的大小不够,出现数组越界情况

一.算法设计

显然,对于这个二维图的变化过程,我们可以用宽度搜索的算法来解决。我们从起点出发,向上下左右四个方向进行搜索,当搜索到O时候,将该坐标入队,并且放在一个临时的vector中(记录坐标,用于后面将O变为X)

每当访问一个结点,要记得将visited数组赋值为已访问状态。搜索过程注意抛弃掉一些越界的无效的点,超出左右上下边界的点。

如果搜索到X,则不用入队,继续循环队列中的元素。
如果搜索到O,将该结点入队的同时,向四个方向分别探索查看是否能继续入队。

最后,判断O的时候还要注意是否为边界上的O,这里我使用了一个flag来判断一个连通的O分量中是否存在边界O的情况

二.实现代码

class Solution {
public:
	//四个搜索方向
    int dir[4][2] ={{1,0},{-1,0},{0,1},{0,-1}};
    void solve(vector<vector<char>>& board) {
    	//当传入图为空的情况
        if(board.empty()) return;
        
        int col = board[0].size();
        int row = board.size();
        queue<pair<int,int>> q;
        int visited[1500][1500] = {0};
        vector<pair<int,int>> vp;
        bool is_board;
        pair<int,int> x;
        pair<int,int> temp;
        
        for (int i = 0; i < row; i++){
            for (int j = 0; j < col; j++){
                vp.clear();
                is_board = false;
                if(!visited[i][j]){
                    pair<int,int> start(i,j);
                    q.push(start);
                    //宽度搜索
                    while(!q.empty()){
                        temp = q.front();
                        q.pop();
                        if(!visited[temp.first][temp.second]){
                            visited[temp.first][temp.second] = 1;
                            //访问到X
                            if(board[temp.first][temp.second] == 'X') continue;
                            //访问到O
                            else{
                            	vp.push_back(temp);
                            	//判断是否为边界O
                                if(temp.first == 0 || temp.first == row-1 
                                || temp.second == 0 || temp.second == col-1){
                                    is_board = true;
                                }
							}
							//若该结点为O,则向四个方向进行宽度搜索
                            for(int k = 0; k < 4; k++){
                            	x.first = temp.first + dir[k][0];
                            	x.second = temp.second + dir[k][1];
                            	//超出边界的结点舍去
                            	if(x.first < 0 || x.first >= row || x.second < 0 || x.second >= col ){
                                	continue;
                            	}
                            	else{
                                	if(board[x.first][x.second] == 'O' && !visited[x.first][x.second]){
                                    	q.push(x);
                                	}
                            	}
                        	}
                        }
                    }
                }
                //将非边界的O赋值为X
                if(!is_board){
                    for(int k = 0; k < vp.size(); k++){
                        board[vp[k].first][vp[k].second] = 'X';
                    }
                }
            }
        }
    }
};

猜你喜欢

转载自blog.csdn.net/dickdick111/article/details/82990550
今日推荐