经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
LeetCode 队列与BFS--岛屿的数量
来源:cnblogs  作者:Ryan_M  时间:2018/12/12 9:51:47  对本文有异议

tags = ["leetcode","队列","BFS","C++","Go"]

岛屿的个数

给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例1:

  1. 输入:
  2. 11110
  3. 11010
  4. 11000
  5. 00000
  6. 输出: 1

示例2:

  1. 输入:
  2. 11000
  3. 11000
  4. 00100
  5. 00011
  6. 输出: 3

分析

这道题的解法有很多,但本帖用广度优先搜索BFS来解答。
本题输入是一个二维数组,判断一个岛屿的要素是判断是否该陆地(1)上下左右是否被水(0)包围,也就是说,岛屿的数量=联通陆地(1)的数量。
BFS算法题解如下,通过找到为岛(1)的初始点,然后对临近的岛屿进行依次访问,利用队列对访问的岛屿进行储存,如下列图示:

  1. +----->
  2. +-+
  3. +1|1 1 1 0
  4. +-+
  5. | 1 1 0 1 0
  6. |
  7. v 1 1 0 0 0
  8. 0 0 0 0 0

当找到初始(1)的时候,将其坐标入队,依据队列的FIFO特性,从队列中取出坐标,对其坐标的上下左右元素进行访问,如果临近的元素为陆地(1),则将其坐标加入队列中等待访问,如果该元素已经被访问,则跳过,重复这一过程,直到队列为空,说明元素周围再也没有陆地,便可看作岛屿。访问过的(1)认为的变为(0)便于后续对未访问的陆地进行查找,岛屿的数量就等于队列为空的遍历次数。其代码如下:

C++实现

  1. class Solution {
  2. private:
  3. queue<int> que;
  4. int count=0;
  5. int x=0;
  6. int y=0;
  7. int xx=0;
  8. int yy=0;
  9. public:
  10. int numIslands(vector<vector<char>>& grid) {
  11. int rows=grid.size();
  12. int cols=rows>0?grid[0].size():0;
  13. int dx[]={-1,0,1,0};
  14. int dy[]={0,1,0,-1};
  15. if(rows==0||cols==0){
  16. return 0;
  17. }
  18. for(int i=0;i<rows;i++){
  19. for(int j=0;j<cols;j++){
  20. //cout<<rows<<cols<<endl;//外部两个for循环为从上到下从左到右寻找未访问的陆地,因为访问过的陆地都已经被置零
  21. if(grid[i][j]=='1'){
  22. que.push(i);
  23. que.push(j);
  24. grid[i][j]='0';
  25. while(!que.empty()){
  26. x=que.front();
  27. que.pop();
  28. y=que.front();
  29. que.pop();
  30. for(int k=0;k<4;k++){
  31. xx=x+dx[k];
  32. yy=y+dy[k];
  33. if(xx<0||xx>=rows||yy<0||yy>=cols){
  34. continue;
  35. }
  36. if(grid[xx][yy]=='1'){
  37. grid[xx][yy]='0';
  38. que.push(xx);
  39. que.push(yy);
  40. }
  41. }
  42. }
  43. count++;//队列为空的次数=岛屿的数量
  44. }
  45. }
  46. }
  47. return count;
  48. }
  49. };

Go实现

由于go语言没有队列queue包,我们自己建一个:

  1. package queue
  2. //Item any type's item
  3. type Item interface {
  4. }
  5. //ItemQueue is store items
  6. type ItemQueue struct {
  7. items []Item
  8. }
  9. //ItemQueuer is a interface
  10. type ItemQueuer interface {
  11. New() ItemQueue
  12. Push(t Item)
  13. Pop() *Item
  14. Empty() bool
  15. Size() int
  16. }
  17. //Push a new item
  18. func (s *ItemQueue) Push(t Item) {
  19. s.items = append(s.items, t)
  20. }
  21. //Pop a front item
  22. func (s *ItemQueue) Pop() {
  23. s.items = s.items[1:]
  24. }
  25. //Empty of items
  26. func (s *ItemQueue) Empty() bool {
  27. return len(s.items) == 0
  28. }
  29. //Size of items
  30. func (s *ItemQueue) Size() int {
  31. return len(s.items)
  32. }
  33. //Front of items
  34. func (s *ItemQueue) Front() Item {
  35. return s.items[0]
  36. }
  37. //Back of items
  38. func (s *ItemQueue) Back() Item {
  39. return s.items[len(s.items)-1]
  40. }

我们用接口实现了类似C++泛型的queue类,下面是go语言实现:

  1. package main
  2. import (
  3. "fmt"
  4. "self/queue"
  5. "time"
  6. )
  7. var que queue.ItemQueue//声明一个队列变量
  8. var m = [][]byte{
  9. {'1', '1', '0', '1', '0'},
  10. {'1', '1', '0', '1', '0'},
  11. {'1', '1', '0', '1', '1'},
  12. {'0', '0', '1', '1', '0'},
  13. }
  14. func main() {
  15. start := time.Now()
  16. coun := numIslands(m)
  17. fmt.Printf("the num of isl is %v", coun)
  18. cost := time.Since(start)
  19. fmt.Printf("Cost %s", cost)
  20. }
  21. func numIslands(grid [][]byte) int {
  22. var que queue.ItemQueue
  23. var x, y, xx, yy, count, rows, cols int = 0, 0, 0, 0, 0, 0, 0
  24. rows = len(grid)
  25. if rows > 0 {
  26. cols = len(grid[0])
  27. } else {
  28. cols = 0
  29. }
  30. var dx, dy = []int{-1, 0, 1, 0}, []int{0, 1, 0, -1}
  31. if rows == 0 || cols == 0 {
  32. return 0
  33. }
  34. for i := 0; i < rows; i++ {
  35. for j := 0; j < cols; j++ {
  36. if grid[i][j] == '1' {
  37. que.Push(i)
  38. que.Push(j)
  39. grid[i][j] = '0'
  40. for !que.Empty() {
  41. x = que.Front().(int)//因为储存的是坐标,所以是int,这里要强制转化,因为que.Front()返回的是interface{}类型
  42. que.Pop()
  43. y = que.Front().(int)
  44. que.Pop()
  45. for k := 0; k < 4; k++ {
  46. xx = x + dx[k]
  47. yy = y + dy[k]
  48. if xx < 0 || xx >= rows || yy < 0 || yy >= cols {
  49. continue
  50. }
  51. if grid[xx][yy] == '1' {
  52. grid[xx][yy] = '0'
  53. que.Push(xx)
  54. que.Push(yy)
  55. }
  56. }
  57. }
  58. count++
  59. }
  60. }
  61. }
  62. return count
  63. }
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号