chengchengxu15 / CS-leaning

1 stars 1 forks source link

200. Number of Islands #46

Closed chengchengxu15 closed 3 years ago

chengchengxu15 commented 3 years ago

https://leetcode.com/problems/number-of-islands/

Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.

An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

chengchengxu15 commented 3 years ago

my solution DFS, like 102. Binary Tree Level Order Traversal


class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        m = len(grid)
        if m == 0:return 0
        n = len(grid[0])
        res = 0

        def delete_one_land(cell,grid,m,n):
            list_cell_for_this_land = [cell]
            while list_cell_for_this_land:
                cell = list_cell_for_this_land.pop()
                i,j = cell
                if grid[i][j] == '0':
                    continue
                grid[i][j] = '0'
                if i > 0 and  grid[i-1][j] == '1':list_cell_for_this_land.append((i-1,j))
                if j > 0 and  grid[i][j-1] == '1':list_cell_for_this_land.append((i,j-1))
                if i < m-1 and  grid[i+1][j] == '1':list_cell_for_this_land.append((i+1,j))
                if j < n-1 and  grid[i][j+1] == '1':list_cell_for_this_land.append((i,j+1))

        for k in range(m):
            for l in range(n):
                if grid[k][l] == '1':
                    res += 1
                    cell = (k,l)
                    delete_one_land(cell,grid,m,n)

        return res
chengchengxu15 commented 3 years ago

DFS: solution:

https://leetcode-cn.com/problems/number-of-islands/solution/number-of-islands-shen-du-you-xian-bian-li-dfs-or-/

class Solution:
    def numIslands(self, grid: [[str]]) -> int:
        def dfs(grid, i, j):
            if not 0 <= i < len(grid) or not 0 <= j < len(grid[0]) or grid[i][j] == '0': return
            grid[i][j] = '0'
            dfs(grid, i + 1, j)
            dfs(grid, i, j + 1)
            dfs(grid, i - 1, j)
            dfs(grid, i, j - 1)
        count = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1':
                    dfs(grid, i, j)
                    count += 1
        return count
chengchengxu15 commented 3 years ago

方法三:并查集 同样地,我们也可以使用并查集代替搜索。

为了求出岛屿的数量,我们可以扫描整个二维网格。如果一个位置为 11,则将其与相邻四个方向上的 11 在并查集中进行合并。

最终岛屿的数量就是并查集中连通分量的数目。

作者:LeetCode 链接:https://leetcode-cn.com/problems/number-of-islands/solution/dao-yu-shu-liang-by-leetcode/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class UnionFind:
    def __init__(self, grid):
        m, n = len(grid), len(grid[0])
        self.count = 0
        self.parent = [-1] * (m * n)
        self.rank = [0] * (m * n)
        for i in range(m):
            for j in range(n):
                if grid[i][j] == "1":
                    self.parent[i * n + j] = i * n + j
                    self.count += 1

    def find(self, i):
        if self.parent[i] != i:
            self.parent[i] = self.find(self.parent[i])
        return self.parent[i]

    def union(self, x, y):
        rootx = self.find(x)
        rooty = self.find(y)
        if rootx != rooty:
            if self.rank[rootx] < self.rank[rooty]:
                rootx, rooty = rooty, rootx
            self.parent[rooty] = rootx
            if self.rank[rootx] == self.rank[rooty]:
                self.rank[rootx] += 1
            self.count -= 1

    def getCount(self):
        return self.count

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        nr = len(grid)
        if nr == 0:
            return 0
        nc = len(grid[0])

        uf = UnionFind(grid)
        num_islands = 0
        for r in range(nr):
            for c in range(nc):
                if grid[r][c] == "1":
                    grid[r][c] = "0"
                    for x, y in [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]:
                        if 0 <= x < nr and 0 <= y < nc and grid[x][y] == "1":
                            uf.union(r * nc + c, x * nc + y)

        return uf.getCount()