130被围绕的区域(深度优先搜索)

1、题目描述

给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。

找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

2、示例

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'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

3、题解

基本思想:dfs,遍历非边界所有的O,然后dfs查找所有连通的O,pos记录连通的O的位置,判断连通中的O是否存在位于边界的O,存在的话flag=1,将这些位置的O置位X。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class Solution {
public:
	int flag = 0;  //标记连通的O是否被X包围,0是包围,1是没有包围(当连通的O存在边界上时flag=1)
	vector<vector<int>> pos;  //记录连通的O的位置,如果flag=0将这些位置的O置位X
	void solve(vector<vector<char>>& board) {
		//简化版:深度优先搜索
		vector<vector<bool>> visited(board.size(), vector<bool>(board[0].size(), false));
		for (int i = 0; i < board.size(); i++)
		{
			for (int j = 0; j < board[i].size(); j++)
			{
				if (board[i][j] == 'O' && !visited[i][j])
				{
					Recursion(board, i, j, visited);
					if (flag == 0)
					{
						for(auto v:pos)
							board[v[0]][v[1]] = 'X';
					}
					flag = 0;
					pos.clear();
				}
			}
		}
	}
	void Recursion(vector<vector<char>>& board, int i, int j, vector<vector<bool>>& visited)
	{
		if(i<0||i>=board.size()||j<0||j>=board[i].size())
			return;
		if(board[i][j] != 'O' || visited[i][j])
			return;
		pos.push_back({ i,j });
		visited[i][j] = true;
		if (i == 0 || i == board.size() - 1 || j == 0 || j == board[i].size() - 1)
			flag = 1;
		Recursion(board, i - 1, j, visited);
		Recursion(board, i + 1, j, visited);
		Recursion(board, i, j - 1, visited);
		Recursion(board, i, j + 1, visited);
	}
};
class Solution1 {
public:
	int flag = 0;  //标记连通的O是否被X包围,0是包围,1是没有包围(当连通的O存在边界上时flag=1)
	vector<vector<int>> pos;  //记录连通的O的位置,如果flag=0将这些位置的O置位X
	void solve(vector<vector<char>>& board) {
		//基本思想:dfs,遍历非边界所有的O,然后dfs判断查找连通的O是否存在位于边界的O,存在的话flag=1
		if (board.size() == 0)
			return;
		//记录O是否被访问过
		vector<vector<bool>> visited(board.size(), vector<bool>(board[0].size(), false));
		//遍历非边界所有的O
		for (int i = 1; i < board.size() - 1; i++)
		{
			for (int j = 1; j < board[i].size() - 1; j++)
			{
				if (board[i][j] == 'O' && !visited[i][j])
				{
					Recursion(board, i, j, visited);
					//flag=0,pos里记录的连通的O被X包围,置为X
					if (flag == 0)
					{
						for (int k = 0; k < pos.size(); k++)
						{
							board[pos[k][0]][pos[k][1]] = 'X';
						}
					}
					flag = 0;
					pos.clear();
				}
			}
		}
	}
	void Recursion(vector<vector<char>>& board, int i, int j, vector<vector<bool>>& visited)
	{
		pos.push_back({ i,j });
		visited[i][j] = true;
		//当连通的O存在边界上时,flag=1
		if (i == 0 || i == board.size() - 1 || j == 0 || j == board[i].size() - 1)
		{
			flag = 1;
		}
		if (i - 1 >= 0 && board[i - 1][j] == 'O' && !visited[i - 1][j])
			Recursion(board, i - 1, j, visited);
		if (i + 1 < board.size() && board[i + 1][j] == 'O' && !visited[i + 1][j])
			Recursion(board, i + 1, j, visited);
		if (j - 1 >= 0 && board[i][j - 1] == 'O' && !visited[i][j - 1])
			Recursion(board, i, j - 1, visited);
		if (j + 1 < board[i].size() && board[i][j + 1] == 'O' && !visited[i][j + 1])
			Recursion(board, i, j + 1, visited);
	}
};
int main()
{
	Solution solute;
	vector<vector<char>> board = {
		{'O', 'O', 'O' },
		{'O', 'O', 'O' },
		{'O', 'O', 'O' }
	};
	solute.solve(board);
	for (int i = 0; i < board.size(); i++)
	{
		for_each(board[i].begin(), board[i].end(), [](const char c) {cout << c << " "; });
		cout << endl;
	}
	return 0;
}

 

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值