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
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM