[LeetCode] BFS解决的题目
一.130 Surrounded Regions(https://leetcode.com/problems/surrounded-regions/description/)
题目:

解法:
这道题的意思是将所有被X包围的O都变为X(边缘的不算),我们可以维护一个队列,先把四周的O的位置放进队列中,并把这个位置的值变为Y。然后每次从队列中拿出一个位置,把这个位置四周为O的位置的值变为Y,再把这个位置放进队列(为什么要先变值再进队列呢?在下一道题中会说)。一直到队列为空时,我们就成功地把所有直接或间接地与边缘的O相连的其他O变为了Y,剩余的O就是被X包围的了。然后遍历一遍,把为O的位置变为X,为Y的位置变为O,就得出结果了。
这道题利用到了BFS(宽度优先搜索)的思想,那么用深度优先是否可以呢?据说会TLE,因为图可能很大,递归会导致栈溢出。但是,我认为分别用这两种不同的方法思考一下这道题,可以锻炼利用bfs和dfs解题的思想。
下面是代码:
class Solution {
public:
void solve(vector<vector<char>>& board) {
queue<int> x;
queue<int> y;
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') {
x.push(i);
y.push(j);
board[i][j] = 'Y';
}
}
}
while (!x.empty() && !y.empty()) {
int i = x.front();
int j = y.front();
x.pop();
y.pop();
if (i - >= && board[i - ][j] == 'O') {
x.push(i - );
y.push(j);
board[i - ][j] = 'Y';
}
if (i + < board.size() && board[i + ][j] == 'O') {
x.push(i + );
y.push(j);
board[i + ][j] = 'Y';
}
if (j - >= && board[i][j - ] == 'O') {
x.push(i);
y.push(j - );
board[i][j - ] = 'Y';
}
if (j + < board[].size() && board[i][j + ] == 'O') {
x.push(i);
y.push(j + );
board[i][j + ] = 'Y';
}
}
for (int i = ; i < board.size(); i++) {
for (int j = ; j < board[i].size(); j++) {
if (board[i][j] == 'Y') {
board[i][j] = 'O';
}
else {
board[i][j] = 'X';
}
}
}
}
};
二. 200 Number of Islands(https://leetcode.com/problems/number-of-islands/description/)
题目:

解法:
这道题的基本思想跟上面一道差不多,也是用bfs,维护一个队列:
当遇到1的时候,把它改为0,进队列;(每次遇到新的island时)
每次把一个位置出队列,并把这个位置四周为1的位置改为0,然后把这些位置放入队列中。当队列为空时,代表已经找到一个island的所有1了,结果+1。
解法是简单的,但我做题的时候还是踩了不少坑:
(1)我用了三层循环去写,因为我想着要判断什么时候所有位置都为0,但其实是多此一举,只需要遍历每一个位置就行了。
(2)我一开始是先把位置放进队列,在出队列的时候才把这个位置的值变为0,但这是不对的:这样会造成一个位置的多次进队列(细想一下吧,出队列的时候才变为0,那在进队列到出队列的过程中这个位置的值还是1,还是会被其他位置检测到,多次加进队列),肯定会TLE。因此一定要先把值变为0,再加进队列。
代码如下:
class Solution {
public:
int numIslands(vector<vector<char> >& grid) {
int ans = ;
queue<int> x, y;
for (int i = ; i < grid.size(); i++ ) {
for (int j = ; j < grid[].size(); j++) {
if (grid[i][j] == '') {
x.push(i);
y.push(j);
grid[i][j] = '';
while (!x.empty() && !y.empty()) {
int i = x.front();
int j = y.front();
x.pop();
y.pop();
if (i - >= && grid[i - ][j] == '') {
x.push(i - );
y.push(j);
grid[i - ][j] = '';
}
if (i + < grid.size() && grid[i + ][j] == '') {
x.push(i + );
y.push(j);
grid[i + ][j] = '';
}
if (j - >= && grid[i][j - ] == '') {
x.push(i);
y.push(j - );
grid[i][j - ] = '';
}
if (j + < grid[].size() && grid[i][j + ] == '') {
x.push(i);
y.push(j + );
grid[i][j + ] = '';
}
}
ans++;
}
}
}
return ans;
}
};
或者:
class Solution {
public:
int numIslands(vector<vector<char> >& grid) {
int ans = ;
for (int i = ; i < grid.size(); i++ ) {
for (int j = ; j < grid[].size(); j++) {
if (grid[i][j] == '') {
bfs(grid, i, j);
ans++;
}
}
}
return ans;
}
void bfs(vector<vector<char> >& grid, int i, int j) {
grid[i][j] = '';
if (i - >= && grid[i - ][j] == '') {
bfs(grid, i - , j);
}
if (i + < grid.size() && grid[i + ][j] == '') {
bfs(grid, i + , j);
}
if (j - >= && grid[i][j - ] == '') {
bfs(grid, i, j - );
}
if (j + < grid[].size() && grid[i][j + ] == '') {
bfs(grid, i, j + );
}
}
};
三.542 01 Matrix
题目:

解法:

代码:
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
vector<vector<int> > ans = matrix;
queue<int> x, y;
for (int i = ; i < ans.size(); i++) {
for (int j = ; j < ans[].size(); j++) {
if (matrix[i][j] == ) {
ans[i][j] = ;
x.push(i);
y.push(j);
}
else {
ans[i][j] = -;
}
}
}
while (!x.empty() && !y.empty()) {
int i = x.front(), j = y.front();
x.pop();
y.pop();
if (i - >= && ans[i - ][j] == -) {
ans[i - ][j] = ans[i][j] + ;
x.push(i - );
y.push(j);
}
if (i + < ans.size() && ans[i + ][j] == -) {
ans[i + ][j] = ans[i][j] + ;
x.push(i + );
y.push(j);
}
if (j - >= && ans[i][j - ] == -) {
ans[i][j - ] = ans[i][j] + ;
x.push(i);
y.push(j - );
}
if (j + < ans[].size() && ans[i][j + ] == -) {
ans[i][j + ] = ans[i][j] + ;
x.push(i);
y.push(j + );
}
}
return ans;
}
};
2018.1.7补充:
上面这一题,重做了一下,想到一个问题: 为什么可以不判断一下就直接ans[i][j] + 1呢?
题目要求离最近的0的距离,而BFS是一层层叠加的、从小到大的,在if处加了ans[i + 1][j] == -1的判断,说明要已修改的值是不能再修改的,满足离最近的0的距离的要求。(描述得不是很清楚,不过自己能回想起就对了)
LeetCode上面还有其他一些用BFS解决的问题,比如Word Ladder,但在前面已经写过了。
[LeetCode] BFS解决的题目的更多相关文章
- 有关dfs、bfs解决迷宫问题的个人见解
可以使用BFS或者DFS方法解决的迷宫问题! 题目如下: kotori在一个n*m迷宫里,迷宫的最外层被岩浆淹没,无法涉足,迷宫内有k个出口.kotori只能上下左右四个方向移动.她想知道有多少出口是 ...
- BFS广搜题目(转载)
BFS广搜题目有时间一个个做下来 2009-12-29 15:09 1574人阅读 评论(1) 收藏 举报 图形graphc优化存储游戏 有时间要去做做这些题目,所以从他人空间copy过来了,谢谢那位 ...
- BFS解决九宫重排问题
问题 1426: [蓝桥杯][历届试题]九宫重排 时间限制: 1Sec 内存限制: 128MB 提交: 215 解决: 47 题目描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个 ...
- LeetCode All in One 题目讲解汇总(转...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 如果各位看官们,大神们发现了任何错误,或是代码无法通 ...
- leetcode-78-子集(用bfs解决)
题目描述: 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3], [1] ...
- 利用BFS解决拯救007问题 -- 数据结构
题目: 7-1 拯救007 (30 分) 在老电影“007之生死关头”(Live and Let Die)中有一个情节,007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 直接 ...
- LeetCode All in One 题目讲解汇总(持续更新中...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...
- [LeetCode] 链表反转相关题目
暂时接触到LeetCode上与链表反转相关的题目一共有3道,在这篇博文里面总结一下.首先要讲一下我一开始思考的误区:链表的反转,不是改变节点的位置,而是改变每一个节点next指针的指向. 下面直接看看 ...
- leetcode BFS解题思路
Word Ladder 思路一:单向bfs, 使用visited数组记录哪些已经访问过了, 访问过的就不允许再次入队, 同时这里想到的是使用26个英文字母,枚举可能的取值, 类似brute force ...
随机推荐
- (Java后端 Java web)面试时如何展示自己非技术方面的能力(其实就是综合能力)
这篇文章的适用范围其实不仅限于Java后端或Java Web,不过其中有些是拿这方面举例的,在其它方面,大家可以举一反三,应该也能得到些启示. 我们在面试时,会发现有些候选人技术不错,比如在Java ...
- 学习如何看懂SQL Server执行计划(三)——连接查询篇
三.连接查询部分 --------------------嵌套循环-------------------- /* UserInfo表数据少.Coupon表数据多嵌套循环可以理解为就是两层For循环,外 ...
- 使用VLC创建组播流
vlc既是一个播放器,又可以成为一个流媒体服务器.最近需要做udp组播播放相关的东西,需要先在本地搭建一个udp组播服务器,因为机器上本来就装有vlc,所以就用它了. 第一步: 点击媒体->流 ...
- HDU1142 A Walk Through the Forest(最短路+DAG)
A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- 文件上传之--内存溢出(System.OutOfMemoryException)
两周前就想把这点经验记录下来了,由于拖延症上身,直到刚才突然想起这件未完成的任务,今天是1024,在这个特别的日子里,祝所有程序猿兄弟姐妹们节日快乐! 上传功能一直很正常,直到上传了个500多兆的文件 ...
- 在Eclipse里面使用git上传项目到码云
Eclispe上使用git 1.安装git 按照下图的步骤: 安装过就不用再安装了,没有安装的安装一下! 安装完毕之后:需要做一些初始化的设置: 2.上传项目到码云上 1.首先在码云上建立一个项目 2 ...
- 框架应用 : Spring MVC - 开发详述
软件开发中的MVC设计模式 软件开发的目标是减小耦合,让模块之前关系清晰. MVC模式在软件开发中经常和ORM模式一起应用,主要作用是将(数据抽象,数据实体传输和前台数据展示)分层,这样前台,后台,数 ...
- Inno Setup打包注意事项
Inno Setup是一个开源的,商业的,快捷的脚本打包工具. 具体打包流程根据界面提示就可以搞定,下面讲解几个注意事项 1.在安装包进行安装的过程当中,很多程序都需要修改配置信息,这就要求我们在安装 ...
- win10 uwp 九幽图床
本文主要是图片加水印自动上传,代码已经上传github. 图片加水印,我的方法,简单,一个好的方法是毒逆天大神的图片加水印方法或http://daily.zhihu.com/story/8812028 ...
- ASP.NET没有魔法——ASP.NET MVC 直连路由(特性路由)
之前对Controller创建的分析中,知道了Controller的创建是有两个步骤组成,分别是Controller的类型查找以及根据类型创建Controller实例. 在查询Controller的类 ...