Surrounded Regions (包围区域)

Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

For example,

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

本题目意思是给定一个棋盘,由x 和o组成,把所有被包围的o变成x。这题目看起来比较像围棋, 如果一个o上下左右都是x那它就叫做被包围了,个人认为正向思维可能不是很好解,直接找哪些被围住了是一件比较困难的事,这里我采用逆向思维,找到那些没有被围住的位置,然后标记出来,最后把那些没被标记的设置为x。那么哪些o是没有被围住的呢? 仔细观察思考可以发现,在最外面一圈的o肯定不会被围住,因为它们至少有一个方向上什么也没有了,相当于围墙。那其实与这些“围墙”上的o相连的o也自然不会被围住。 其实这和围棋规则很像的。 于是我这里就采用设置访问位+深度优先搜索的策略来找到那些没有被围住的o, 起点就从“围墙” 最外面的一圈o开始。其实如果最外面一圈没有o,那里面所有的o都应该被置为x了。

这里我的程序使用一个visit vetor作为访问标志矩阵,每一个位置初始为n,这个矩阵有两个作用 ,第一个作用是表示我们没访问过的board位置,如果visit[i][j] 是'n' 表示 要么board[i][j]没有访问过,要么表示board[i][j]访问过了但是不是o字符。visit[i][j]如果是'y' 则表示board[i][j]被访问过了并且board[i][j]是不需要被设置为x的。

这题目有点蛋疼的地方是它没说是X,结果提交的第一次交的小写的x和小写的o。。坑爹。  还有就是在dfs函数中,有一个减号被我写成了加号,导致的结果就是

结果我丧心病狂的用最愚蠢的办法去调试 花了20多分钟 :






真是给自己蠢哭了。。。

class Solution {
public:
	void solve(vector<vector<char>> &board) {
		// visit 大小与board相同,内容为y或者n
		// row,col变量分别表示board的行数和列数
		vector<vector<char> > visit = board;
		if (board.size() < 2) return;
		if (board[0].size() < 2) return;
		int row = board.size(), col = board[0].size();
		// visit初始化全为‘n’
		for (int i = 0; i < row; ++i)
		{
			for (int j = 0; j < col; ++j)
				visit[i][j] = 'n';
		}

		// 这个循环从“围墙”的左右两列中找到深度搜索的开始节点
		// 然后进行搜索看哪些o不需要被设置为x
		for (int i = 0; i < row; ++i)
		{
			// 如果board[i][0]没有访问过并且是‘o'那就从它开始深度搜索
			if (board[i][0] == 'O' && visit[i][0] == 'n')
			{
				DFS(board, visit, i, 0, row, col);
			}
			// 下面是利用同一个循环同时搜索“围墙”的右边一列
			if (board[i][col - 1] == 'O' &&  visit[i][col - 1] == 'n')
			{
				DFS(board, visit, i, col - 1, row, col);
			}
		}

		// 下面的循环从行开始搜索,搜索第一行和最后一行
		for (int j = 0; j < col; ++j)
		{
			if (board[0][j] == 'O' && visit[0][j] == 'n')
			{
				DFS(board, visit, 0, j, row, col);
			}
			if (board[row - 1][j] == 'O' &&  visit[row - 1][j] == 'n')
			{
				DFS(board, visit, row - 1, j, row, col);
			}
		}

		// 下面的循环是根据visit矩阵的状态去把o设置成x
		for (int i = 0; i < row; ++i)
		{
			for (int j = 0; j < col; ++j)
			{
				if (visit[i][j] == 'n' && board[i][j] == 'O')
					board[i][j] = 'X';
			}
		}

	}

private:
	void DFS(vector<vector<char>> &board, vector<vector<char>> &visit, int i, int j, int row, int col)
	{
		stack<pair<int, int> > m_stack;
		m_stack.push(make_pair(i, j));
		visit[i][j] = 'y';
		while (!m_stack.empty())
		{
			pair<int, int> tmp = m_stack.top();
			int x = tmp.first, y = tmp.second;
			// 向上搜索
			if (x > 0 && x < row && visit[x - 1][y] == 'n' && board[x - 1][y] == 'O')
			{
				m_stack.push(make_pair(x - 1, y));
				visit[x - 1][y] = 'y';
			}
			// 向下搜索
			else if (x >= 0 && x < row - 1 && visit[x + 1][y] == 'n' && board[x + 1][y] == 'O')
			{
				m_stack.push(make_pair(x + 1, y));
				visit[x + 1][y] = 'y';
			}
			// 向左搜索
			else if (y > 0 && y < col && visit[x][y - 1] == 'n' && board[x][y - 1] == 'O')
			{
				m_stack.push(make_pair(x, y - 1));
				visit[x][y - 1] = 'y';
			}
			// 向右搜索
			else if (y >= 0 && y < col - 1 && visit[x][y + 1] == 'n' && board[x][y + 1] == 'O')
			{
				m_stack.push(make_pair(x, y + 1));
				visit[x][y + 1] = 'y';
			}
			else
			{
				m_stack.pop();
			}
		}
	}
};


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这里提供一种基于深度优先搜索(DFS)算法的解决方案,具体实现如下: ```lua -- 定义一个函数,用于判断某个元素所在的连通区域是否被其他连通区域完全包围 function is_surrounded(grid, row, col) -- 定义一个标记数组,用于记录每个元素是否已经被遍历过 local visited = {} for i = 1, #grid do visited[i] = {} for j = 1, #grid[i] do visited[i][j] = false end end -- 定义一个函数,用于执行深度优先搜索 local function dfs(r, c) -- 如果当前元素已经被遍历过,直接返回 if visited[r][c] then return end -- 标记当前元素为已遍历 visited[r][c] = true -- 如果当前元素位于边界上,说明它所在的连通区域没有被完全包围 if r == 1 or r == #grid or c == 1 or c == #grid[1] then return true end -- 递归遍历当前元素的上下左右四个方向 if dfs(r-1, c) or dfs(r+1, c) or dfs(r, c-1) or dfs(r, c+1) then return true end return false end -- 执行深度优先搜索,并返回结果 return dfs(row, col) end ``` 该函数接受三个参数:一个表示网格的二维数组 `grid`,一个表示元素所在行的索引 `row`,以及一个表示元素所在列的索引 `col`。函数首先创建一个和 `grid` 一样大小的标记数组 `visited`,并将其中所有元素初始化为 `false`。然后定义一个内部函数 `dfs`,用于执行深度优先搜索。该函数首先判断当前元素是否已经被遍历过,如果是则直接返回;否则将当前元素标记为已遍历,并检查当前元素是否位于边界上。如果是,则说明它所在的连通区域没有被完全包围,可以直接返回 `true`;否则递归遍历当前元素的上下左右四个方向,并将搜索结果作为返回值。最后,执行 `dfs(row, col)` 并返回其结果即可。 使用示例: ```lua -- 定义一个二维数组表示网格 local grid = { {1, 1, 1, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 1, 1, 1}, } -- 判断第二行第二列的元素所在的连通区域是否被其他连通区域完全包围 local surrounded = is_surrounded(grid, 2, 2) print(surrounded) -- 输出 false ``` 在上面的示例中,我们定义了一个二维数组 `grid` 表示一个 4x4 的网格,其中 1 表示障碍物,0 表示空地。然后调用 `is_surrounded(grid, 2, 2)` 函数,判断第二行第二列的元素所在的连通区域是否被其他连通区域完全包围。由于该连通区域没有被完全包围,因此返回值为 `false`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值