求连通块个数 - 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)
posted @ 2019-12-15 14:38  但是我拒绝  阅读(1121)  评论(1编辑  收藏  举报