LeetCode 队列与BFS--岛屿的数量
tags = ["leetcode","队列","BFS","C++","Go"]
岛屿的个数
给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例1:
输入:
11110
11010
11000
00000
输出: 1
示例2:
输入:
11000
11000
00100
00011
输出: 3
分析
这道题的解法有很多,但本帖用广度优先搜索BFS
来解答。
本题输入是一个二维数组,判断一个岛屿的要素是判断是否该陆地(1)上下左右
是否被水(0)包围,也就是说,岛屿的数量=联通陆地(1)的数量。
BFS
算法题解如下,通过找到为岛(1)的初始点,然后对临近的岛屿进行依次访问,利用队列对访问的岛屿进行储存,如下列图示:
+----->
+-+
+1|1 1 1 0
+-+
| 1 1 0 1 0
|
v 1 1 0 0 0
0 0 0 0 0
当找到初始(1)的时候,将其坐标入队,依据队列的FIFO
特性,从队列中取出坐标,对其坐标的上下左右
元素进行访问,如果临近的元素为陆地(1),则将其坐标加入队列中等待访问,如果该元素已经被访问,则跳过,重复这一过程,直到队列为空,说明元素周围再也没有陆地,便可看作岛屿。访问过的(1)认为的变为(0)便于后续对未访问的陆地进行查找,岛屿的数量就等于队列为空的遍历次数。其代码如下:
C++实现
class Solution {
private:
queue<int> que;
int count=0;
int x=0;
int y=0;
int xx=0;
int yy=0;
public:
int numIslands(vector<vector<char>>& grid) {
int rows=grid.size();
int cols=rows>0?grid[0].size():0;
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
if(rows==0||cols==0){
return 0;
}
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
//cout<<rows<<cols<<endl;//外部两个for循环为从上到下从左到右寻找未访问的陆地,因为访问过的陆地都已经被置零
if(grid[i][j]=='1'){
que.push(i);
que.push(j);
grid[i][j]='0';
while(!que.empty()){
x=que.front();
que.pop();
y=que.front();
que.pop();
for(int k=0;k<4;k++){
xx=x+dx[k];
yy=y+dy[k];
if(xx<0||xx>=rows||yy<0||yy>=cols){
continue;
}
if(grid[xx][yy]=='1'){
grid[xx][yy]='0';
que.push(xx);
que.push(yy);
}
}
}
count++;//队列为空的次数=岛屿的数量
}
}
}
return count;
}
};
Go实现
由于go语言没有队列queue
包,我们自己建一个:
package queue
//Item any type's item
type Item interface {
}
//ItemQueue is store items
type ItemQueue struct {
items []Item
}
//ItemQueuer is a interface
type ItemQueuer interface {
New() ItemQueue
Push(t Item)
Pop() *Item
Empty() bool
Size() int
}
//Push a new item
func (s *ItemQueue) Push(t Item) {
s.items = append(s.items, t)
}
//Pop a front item
func (s *ItemQueue) Pop() {
s.items = s.items[1:]
}
//Empty of items
func (s *ItemQueue) Empty() bool {
return len(s.items) == 0
}
//Size of items
func (s *ItemQueue) Size() int {
return len(s.items)
}
//Front of items
func (s *ItemQueue) Front() Item {
return s.items[0]
}
//Back of items
func (s *ItemQueue) Back() Item {
return s.items[len(s.items)-1]
}
我们用接口实现了类似C++
泛型的queue
类,下面是go语言
实现:
package main
import (
"fmt"
"self/queue"
"time"
)
var que queue.ItemQueue//声明一个队列变量
var m = [][]byte{
{'1', '1', '0', '1', '0'},
{'1', '1', '0', '1', '0'},
{'1', '1', '0', '1', '1'},
{'0', '0', '1', '1', '0'},
}
func main() {
start := time.Now()
coun := numIslands(m)
fmt.Printf("the num of isl is %v", coun)
cost := time.Since(start)
fmt.Printf("Cost %s", cost)
}
func numIslands(grid [][]byte) int {
var que queue.ItemQueue
var x, y, xx, yy, count, rows, cols int = 0, 0, 0, 0, 0, 0, 0
rows = len(grid)
if rows > 0 {
cols = len(grid[0])
} else {
cols = 0
}
var dx, dy = []int{-1, 0, 1, 0}, []int{0, 1, 0, -1}
if rows == 0 || cols == 0 {
return 0
}
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
if grid[i][j] == '1' {
que.Push(i)
que.Push(j)
grid[i][j] = '0'
for !que.Empty() {
x = que.Front().(int)//因为储存的是坐标,所以是int,这里要强制转化,因为que.Front()返回的是interface{}类型
que.Pop()
y = que.Front().(int)
que.Pop()
for k := 0; k < 4; k++ {
xx = x + dx[k]
yy = y + dy[k]
if xx < 0 || xx >= rows || yy < 0 || yy >= cols {
continue
}
if grid[xx][yy] == '1' {
grid[xx][yy] = '0'
que.Push(xx)
que.Push(yy)
}
}
}
count++
}
}
}
return count
}
LeetCode 队列与BFS--岛屿的数量的更多相关文章
- [LeetCode] Number of Islands 岛屿的数量
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...
- Leetcode 200.岛屿的数量 - DFS、BFS
Leetcode 200 岛屿的数量: DFS利用函数调用栈保证了检索顺序, BFS则需要自己建立队列,把待检索对象按规则入队. class Solution { // DFS解法,8ms/10.7M ...
- [LeetCode] 200. Number of Islands 岛屿的数量
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...
- [LeetCode] 305. Number of Islands II 岛屿的数量 II
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...
- 队列和 BFS —— 栈和 DFS
队列和 BFS: 广度优先搜索(BFS)的一个常见应用是找出从根结点到目标结点的最短路径. 示例 这里我们提供一个示例来说明如何使用 BFS 来找出根结点 A 和目标结点 G 之间的最短路径. 洞悉 ...
- 遍历二叉树 - 基于队列的BFS
之前学过利用递归实现BFS二叉树搜索(http://www.cnblogs.com/webor2006/p/7262773.html),这次学习利用队列(Queue)来实现,关于什么时BFS这里不多说 ...
- 51nod 1276:岛屿的数量 很好玩的题目
1276 岛屿的数量 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 取消关注 有N个岛连在一起形成了一个大的岛屿,如果海平 ...
- 基于循环队列的BFS的原理及实现
文章首发于微信公众号:几何思维 1.故事起源 有一只蚂蚁出去寻找食物,无意中进入了一个迷宫.蚂蚁只能向上.下.左.右4个方向走,迷宫中有墙和水的地方都无法通行.这时蚂蚁犯难了,怎样才能找出到食物的最短 ...
- [LeetCode] Number of Islands II 岛屿的数量之二
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...
随机推荐
- redis 集群目标、集群查看、配置方法及过程、哨兵配置启动
集群目标 主从复制,读写分离:故障切换(通过哨兵实现) 查看集群状态 info replication 配置方法 只设置从数据库就可以了:最佳实践,在主数据库配置masterauth <mast ...
- SQLSERVER中KeyHashValue的作用(下)
SQLSERVER中KeyHashValue的作用(下) 昨天中午跟高文佳童鞋讨论了KeyHashValue的作用,到最后还是没有讨论出结果 昨天晚上德国的兄弟傅文伟做了一下实验,将实验结果交给我 感 ...
- [翻译] ZLHistogramAudioPlot
ZLHistogramAudioPlot A hardware-accelerated audio visualization view using EZAudio, inspired by Audi ...
- 安全预警-防范新型勒索软件“BlackRouter”
近期,出现一种新型勒索软件“BlackRouter”,开发者将其与正常软件恶意捆绑在一起,借助正常软件的下载和安装实现病毒传播,并以此躲避安全软件的查杀.目前,已知的被利用软件有AnyDesk工具(一 ...
- .net mvc HTTP 错误 403.14 - Forbidden Web 服务器被配置为不列出此目录的内容
1. 检查服务器上是否安装了“HTTP重定向”功能和“静态内容压缩”功能(在添加/删除程序或增加角色处安装).这是我所遇到的问题: 2. 应用程序池要被配置为“集成” 3. 把.net 4.0安装在i ...
- 鼠标有但是U盘读取不出来怎么办
我今天就遇到了这个问题,搞了半天最后下了一个驱动人生,查看里面的回答才解决 就是把里面通用串行总控制器设置为隐藏文件可读之后选择把灰色的都删除就好了.具体可以在驱动人生里搜U盘不识别,之后就4,5步即 ...
- Qt如何设置应用ico图标
第一步,创建ico文件.将ico图标文件复制到工程文件夹目录中(注意必须是图标文件,任何格式的改后缀都不行) ,重命名为"myico.ico“.然后在该目录中右击,新建文本文档,并输入一行代 ...
- Python的multiprocessing,Queue,Process
在多线程multiprocessing模块中,有两个类,Queue(队列)和Process(进程): 在Queue.py中也有一个Queue类,这两个Queue的区别? from multiproce ...
- Python 2.7和3.6爬取妹子图网站单页测试图片
1.url= http://www.mzitu.com/74100/x,2为1到23的值 2.用到模块 os 创建文件目录; re模块正则匹配目录名 图片下载地址; time模块 限制下载时间;req ...
- 上手 Kubernetes
一.Kubernetes架构 二.重要的几个概念 1.Pod:最小单元 1.1 一个Pod里可以有多个Container 1.2这些container共享这个pod的同一个网络地址,同一个文件系统,通 ...