求連通塊個數 - BFS、DFS、並查集實現


本文基於leetcode的200.島嶼數量(題目👇)為基礎進行說明

DFS實現
class Solution:
    def numIslands(self, grid) -> int:
        vis = set()
        directx = [-1, 1, 0, 0]
        directy = [0, 0, -1, 1]
        def DFS(x, y):
            if (x, y) in vis:
                return
            vis.add((x, y))
            for i in range(4):
                newx = x + directx[i]
                newy = y + directy[i]
                if -1 < newx < len(grid) and -1 < newy < len(grid[0]):
                    if (newx, newy) not in vis and grid[newx][newy] == '1':
                        DFS(newx, newy)
        s = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1' and (i, j) not in vis:
                    DFS(i, j)
                    # 進行了幾次DFS就有多少塊連通塊
                    s += 1
        return s

BFS實現

DFS和BFS兩種實現方法類似,都是執行了幾次操作,連通塊就有幾個。

class Solution:
    def numIslands(self, grid) -> int:
        if not grid:
            return 0
        row = len(grid)
        col = len(grid[0])
        vis = set()
        directx = [-1, 1, 0, 0]
        directy = [0, 0, -1, 1]
        ans = 0
        for i in range(row):
            for j in range(col):
                if grid[i][j] == '1' and (i, j) not in vis:
                    vis.add((i, j))
                    stack = [(i, j)]
                    ans += 1
                    while len(stack) != 0:
                        x, y = stack.pop(0)
                        for t in range(4):
                            newx, newy = x + directx[t], y + directy[t]
                            if -1 < newx < row and -1 < newy < col and (newx, newy) not in vis and grid[newx][newy] == '1':
                                vis.add((newx, newy))
                                stack.append((newx, newy))
        return ans

並查集實現
class Solution:
    def numIslands(self, grid) -> int:
        directx = [-1, 1, 0, 0]
        directy = [0, 0, -1, 1]
        pre = {}
        if not grid:
            return 0
        row = len(grid)
        col = len(grid[0])
        # 找首領
        def find(node):
            # 初始時,每個人都是自己的首領
            pre.setdefault(node, node)
            while node != pre[node]:
                node = pre[node]
            return node
        # 將兩個集合合並
        def union(x, y):
           pre[find(y)] = find(x)
        for i in range(row):
            for j in range(col):
                if grid[i][j] == "1":
                    for t in range(4):
                        newx, newy = i + directx[t], j + directy[t]
                        if -1 < newx < row and -1 < newy < col and grid[newx][newy] == '1':
                                # 這里的i * col + j是為了將二維轉換為一維,其中col的位置也可以替換成其他值,只要不影響到其他值即可
                                union(i * col + j, newx * col + newy)
        res = set()
        for i in range(row):
            for j in range(col):
                # 判斷一共有幾個大首領就知道有幾個連通塊了。
                if grid[i][j] == "1":
                    res.add(find(i*col+j))
        return len(res)


免責聲明!

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



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