[LeetCode] Surrounded Regions 包围区域
Given a 2D board containing 'X' and 'O'(the letter O), capture all regions surrounded by 'X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region.
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
Explanation:
Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.
这是道关于 XXOO 的题,有点像围棋,将包住的O都变成X,但不同的是边缘的O不算被包围,跟之前那道 Number of Islands 很类似,都可以用 DFS 来解。刚开始我的思路是 DFS 遍历中间的O,如果没有到达边缘,都变成X,如果到达了边缘,将之前变成X的再变回来。但是这样做非常的不方便,在网上看到大家普遍的做法是扫矩阵的四条边,如果有O,则用 DFS 遍历,将所有连着的O都变成另一个字符,比如 \$,这样剩下的O都是被包围的,然后将这些O变成X,把$变回O就行了。代码如下:
解法一:
class Solution {
public:
void solve(vector<vector<char> >& board) {
for (int i = ; i < board.size(); ++i) {
for (int j = ; j < board[i].size(); ++j) {
if ((i == || i == board.size() - || j == || j == board[i].size() - ) && board[i][j] == 'O')
solveDFS(board, i, j);
}
}
for (int i = ; i < board.size(); ++i) {
for (int j = ; j < board[i].size(); ++j) {
if (board[i][j] == 'O') board[i][j] = 'X';
if (board[i][j] == '$') board[i][j] = 'O';
}
}
}
void solveDFS(vector<vector<char> > &board, int i, int j) {
if (board[i][j] == 'O') {
board[i][j] = '$';
if (i > && board[i - ][j] == 'O')
solveDFS(board, i - , j);
if (j < board[i].size() - && board[i][j + ] == 'O')
solveDFS(board, i, j + );
if (i < board.size() - && board[i + ][j] == 'O')
solveDFS(board, i + , j);
if (j > && board[i][j - ] == 'O')
solveDFS(board, i, j - );
}
}
};
很久以前,上面的代码中最后一个 if 中必须是 j > 1 而不是 j > 0,为啥 j > 0 无法通过 OJ 的最后一个大数据集合,博主开始也不知道其中奥秘,直到被另一个网友提醒在本地机子上可以通过最后一个大数据集合,于是博主也写了一个程序来验证,请参见验证 LeetCode Surrounded Regions 包围区域的DFS方法,发现 j > 0 是正确的,可以得到相同的结果。神奇的是,现在用 j > 0 也可以通过 OJ 了。
下面这种解法还是 DFS 解法,只是递归函数的写法稍有不同,但是本质上并没有太大的区别,参见代码如下:
解法二:
class Solution {
public:
void solve(vector<vector<char>>& board) {
if (board.empty() || board[].empty()) return;
int m = board.size(), n = board[].size();
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (i == || i == m - || j == || j == n - ) {
if (board[i][j] == 'O') dfs(board, i , j);
}
}
}
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (board[i][j] == 'O') board[i][j] = 'X';
if (board[i][j] == '$') board[i][j] = 'O';
}
}
}
void dfs(vector<vector<char>> &board, int x, int y) {
int m = board.size(), n = board[].size();
vector<vector<int>> dir{{,-},{-,},{,},{,}};
board[x][y] = '$';
for (int i = ; i < dir.size(); ++i) {
int dx = x + dir[i][], dy = y + dir[i][];
if (dx >= && dx < m && dy > && dy < n && board[dx][dy] == 'O') {
dfs(board, dx, dy);
}
}
}
};
我们也可以使用迭代的解法,但是整体的思路还是一样的,在找到边界上的O后,然后利用队列 queue 进行 BFS 查找和其相连的所有O,然后都标记上美元号。最后的处理还是先把所有的O变成X,然后再把美元号变回O即可,参见代码如下:
解法三:
class Solution {
public:
void solve(vector<vector<char>>& board) {
if (board.empty() || board[].empty()) return;
int m = board.size(), n = board[].size();
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (i != && i != m - && j != && j != n - ) continue;
if (board[i][j] != 'O') continue;
board[i][j] = '$';
queue<int> q{{i * n + j}};
while (!q.empty()) {
int t = q.front(), x = t / n, y = t % n; q.pop();
if (x >= && board[x - ][y] == 'O') {board[x - ][y] = '$'; q.push(t - n);}
if (x < m - && board[x + ][y] == 'O') {board[x + ][y] = '$'; q.push(t + n);}
if (y >= && board[x][y - ] == 'O') {board[x][y - ] = '$'; q.push(t - );}
if (y < n - && board[x][y + ] == 'O') {board[x][y + ] = '$'; q.push(t + );}
}
}
}
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (board[i][j] == 'O') board[i][j] = 'X';
if (board[i][j] == '$') board[i][j] = 'O';
}
}
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/130
类似题目:
参考资料:
https://leetcode.com/problems/surrounded-regions/
https://leetcode.com/problems/surrounded-regions/discuss/41895/Share-my-clean-Java-Code
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Surrounded Regions 包围区域的更多相关文章
- 验证LeetCode Surrounded Regions 包围区域的DFS方法
在LeetCode中的Surrounded Regions 包围区域这道题中,我们发现用DFS方法中的最后一个条件必须是j > 1,如下面的红色字体所示,如果写成j > 0的话无法通过OJ ...
- [LeetCode] 130. Surrounded Regions 包围区域
Given a 2D board containing 'X' and 'O'(the letter O), capture all regions surrounded by 'X'. A regi ...
- [LintCode] Surrounded Regions 包围区域
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...
- Surrounded Regions 包围区域——dfs
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...
- Leetcode: Surrounded regions
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...
- LeetCode: Surrounded Regions 解题报告
Surrounded Regions Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A ...
- LeetCode: Surrounded Regions [130]
[题目] Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is cap ...
- LEETCODE —— Surrounded Regions
Total Accepted: 43584 Total Submissions: 284350 Difficulty: Medium Given a 2D board containing 'X' a ...
- [leetcode]Surrounded Regions @ Python
原题地址:https://oj.leetcode.com/problems/surrounded-regions/ 题意: Given a 2D board containing 'X' and 'O ...
随机推荐
- ASP.NET MVC Controller的激活
最近抽空看了一下ASP.NET MVC的部分源码,顺带写篇文章做个笔记以便日后查看. 在UrlRoutingModule模块中,将请求处理程序映射到了MvcHandler中,因此,说起Controll ...
- 在mongoose中使用$match对id失效的解决方法
Topic.aggregate( //{$match:{_id:"5576b59e192868d01f75486c"}}, //not work //{$match:{title: ...
- helios架构详解(一)服务器端架构
看了“菜鸟耕地”的”.NET开源高性能Socket通信中间件Helios介绍及演示“,觉得这个东西不错.但是由于没有网络编程知识,所以高性能部分我就讲不出来了,主要是想根据开源代码跟大家分享下Heli ...
- VNC软件的安装及使用方法说明
本篇仅为作业... 实验课程:Linux系统 指导老师:刘臣奇 实验机器:联想y410p 实验时间:2016年9月11日 学生学号:140815 姓名:杨文乾 在一台机器安装viewer的同时,在另一 ...
- DataGrid 列头实现国际化语言切换
<DataGrid> <DataGrid.Columns> <DataGridTextColumn Binding="{x:Null}" Width= ...
- 回顾java基础—Java数据类型
1 java数据类型.8种基本类型,3种引用类型 基本类型(也称:原始类型):byte.short.int.long.char.float.double.boolean 引用类型:类,接口,数组 2 ...
- 通过JAXB完成Java对象与XML之间的转换
Java对象转换XML的过程叫marshal. XML转换到Java对象的过程叫unmarshal. 一.Java对象转化为XML 这里省略getter和setter方法 通过标注@XMLRootEl ...
- WebService 概念和工作原理(一)
今天我们一起来学习WebService.它到底是干啥用的? Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集) ...
- jQuery的案例及必知重要的jQuery选择器
Jquery能做什么 访问和操作DOM元素 控制页面样式 对页面事件进行处理 扩展新的jQuery插件 与Ajax技术完美结合 Jquery的优势 体积小,压缩后只有100KB左右 l强大的选择器 出 ...
- angular $http请求
angular使用post.get向后台传参的问题 一.问题的来源 我们都知道向后台传参可以使用get.put,其形式就类似于name=jyy&id=001.但是在ng中我却发现使用$http ...