zoukankan      html  css  js  c++  java
  • 200. 岛屿数量 BFS+DFS+并查集(Python 3)

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

    示例 1:

    输入:
    11110
    11010
    11000
    00000
    
    输出: 1
    

    示例 2:

    输入:
    11000
    11000
    00100
    00011
    
    输出: 3
    

    本题根本是求连通域个数

    • 循环实现广度优先BFS(使用队列):
    from collections import deque
    
    class Solution:
        directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
        
        def numIslands(self, grid: List[List[str]]) -> int:
            m = len(grid) #行
            if m == 0:
                return 0
            n = len(grid[0]) # 列
            marked = [[False for i in range(n)] for i in range(m)]
            count = 0
            
            for i in range(m):
                for j in range(n):
                    if not marked[i][j] and grid[i][j] == '1':
                        queue = deque()
                        count += 1
                        queue.append((i,j))
                        marked[i][j] = True
                        while queue:
                            cur_x, cur_y = queue.popleft() # key step
                            for direction in self.directions:
                                new_i = cur_x + direction[0]
                                new_j = cur_y + direction[1]
                                if 0 <= new_i < m and 0 <= new_j < n and not marked[new_i][new_j] and grid[new_i][new_j] == '1':
                                    queue.append((new_i, new_j))
                                    marked[new_i][new_j] = True
            return count
    
    • 循环实现深度优先DFS(使用栈):
    class Solution:
        directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
    
        def numIslands(self, grid: List[List[str]]) -> int:
            count = 0
            m = len(grid)
            if m == 0:
                return 0
            n = len(grid[0])
            marked = [[False for i in range(n)] for i in range(m)]
            for i in range(m):
                for j in range(n):
                    if not marked[i][j] and grid[i][j] == '1':
                        stack = []
                        stack.append((i, j))
                        marked[i][j] = True
                        count += 1
                        while stack:
                            cur_i, cur_j = stack.pop()
                            for direction in self.directions:
                                new_i = cur_i + direction[0]
                                new_j = cur_j + direction[1]
                                if 0 <= new_i < m and 0 <= new_j < n and not marked[new_i][new_j] and grid[new_i][new_j] == '1':
                                    stack.append((new_i, new_j))
                                    marked[new_i][new_j] = True
            return count
    
    • 递归实现DFS方法:
    class Solution:
        directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
    
        def find(self, grid: List[List[str]], i, j):
            if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]) or grid[i][j] != '1':
                return
            grid[i][j] = '2'
            for direction in self.directions:
                self.find(grid, i + direction[0], j + direction[1])
        
        def numIslands(self, grid: List[List[str]]) -> int:
            count = 0
            m = len(grid)
            if m == 0:
                return 0
            n = len(grid[0])
            for i in range(m):
                for j in range(n):
                    if grid[i][j] == '1':
                        self.find(grid, i, j)
                        count += 1
            return count
    
    • 并查集,只考虑向右和向下两个方向,而不是四个方向
    from typing import List
    class Solution:
        # 并查集
        
        def numIslands(self, grid: List[List[str]]) -> int:
            # 每个节点表示集合的一个元素,每个元素用一个数字表示
            class UnionFind:
                def __init__(self, n: int):
                    self.count = n
                    self.parent = [i for i in range(n)] # 每个元素的树根,开始时为自身
                    self.rank = [1 for _ in range(n)] # 每个节点的初始秩
                
                def getCount(self) -> int:
                    return self.count
                
                def find(self,p): # 递归寻找树根
                    if(p != self.parent[p]):
                        self.parent[p] = self.find(self.parent[p])
                    return self.parent[p]
                
                def union(self, p, q): # 按秩合并,将具有较小秩的树根指向具有较大秩的树根
                    p_root = self.find(p)
                    q_root = self.find(q)
                    if p_root == q_root:
                        return
                    if self.rank[p_root] > self.rank[q_root]:
                        self.parent[q_root] = p_root
                        self.rank[p_root] += 1
                    else:
                        self.parent[p_root] = q_root
                        self.rank[q_root] += 1
                    self.count -= 1
            
            m = len(grid)
            if m == 0:
                return 0
            n = len(grid[0])
    
            def getIndex(x, y):
                return x * n + y
    
            uf = UnionFind(m * n)
            water = 0
    
            for i in range(m):
                for j in range(n):
                    if grid[i][j] == '0':
                        water += 1
                    else:
                        if i + 1 < m and grid[i + 1][j] == '1':
                            uf.union(getIndex(i, j), getIndex(i + 1, j))
                        if j + 1 < n and grid[i][j + 1] == '1':
                            uf.union(getIndex(i, j), getIndex(i, j + 1))
    
            return uf.getCount() - water
    
  • 相关阅读:
    This counter can increment, decrement or skip ahead by an arbitrary amount
    LUT4/MUXF5/MUXF6 logic : Multiplexer 8:1
    synthesisable VHDL for a fixed ratio frequency divider
    Bucket Brigade FIFO SRL16E ( VHDL )
    srl16e fifo verilog
    DualPort Block RAM with Two Write Ports and Bytewide Write Enable in ReadFirst Mode
    Parametrilayze based on SRL16 shift register FIFO
    stm32 spi sdcard fatfs
    SPI bus master for System09 (2)
    SQLSERVER中的自旋锁
  • 原文地址:https://www.cnblogs.com/libbin/p/numIslands.html
Copyright © 2011-2022 走看看