【LeetCode 200】岛屿数量

方法一:染色问题(DFS)

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid:
            return 0
        n,m = len(grid),len(grid[0])
        cnt = 0
        visited = set()
        for i in range(n):
            for j in range(m):
                cnt += self.dfs(grid,visited,i,j)
        return cnt
    
    def dfs(self,grid,visited,i,j):
        n,m = len(grid),len(grid[0])
        if i < 0 or j < 0 or i >= n or j >= m or (i,j) in visited or grid[i][j] == '0':
            return 0
        visited.add((i,j))
        dx = [1,-1,0,0]
        dy = [0,0,1,-1]
        for k in range(4):
            x,y = i+dx[k],j+dy[k]
            self.dfs(grid,visited,x,y)
        return 1

DFS的另一种写法:

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid:
            return 0
        n,m = len(grid),len(grid[0])
        cnt = 0
        visited = set()
        for i in range(n):
            for j in range(m):
                if grid[i][j] == '1' and (i,j) not in visited:
                    cnt += self.dfs(grid,visited,i,j)
        return cnt
    
    def dfs(self,grid,visited,i,j):
        visited.add((i,j))
        n,m = len(grid),len(grid[0])
        dx = [1,-1,0,0]
        dy = [0,0,1,-1]
        for k in range(4):
            x,y = i+dx[k],j+dy[k]
            if 0 <= x < n and 0 <= y < m and (x,y) not in visited and grid[x][y] == '1':
                self.dfs(grid,visited,x,y)
        return 1

 

 

方法二:染色问题(BFS)

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid:
            return 0
        n,m = len(grid),len(grid[0])
        cnt = 0
        visited = set()
        for i in range(n):
            for j in range(m):
                cnt += self.bfs(grid,visited,i,j)
        return cnt
    
    def bfs(self,grid,visited,i,j):
        n,m = len(grid),len(grid[0])
        dx = [1,-1,0,0]
        dy = [0,0,1,-1]
        if i < 0 or j < 0 or i >= n or j >= m or (i,j) in visited or grid[i][j] == '0':
            return 0
        visited.add((i,j))
        queue = collections.deque()
        queue.append((i,j))
        while queue:
            cur_x,cur_y = queue.popleft()
            for k in range(4):
                x,y = cur_x+dx[k],cur_y+dy[k]
                if x >= 0 and y >= 0 and x < n and y < m and (x,y) not in visited and grid[x][y] == '1':
                    visited.add((x,y))
                    queue.append((x,y))
        return 1

方法三:并查集

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid:
            return 0
        n,m = len(grid),len(grid[0])
        dx = [1,-1,0,0]
        dy = [0,0,1,-1]
        cnt = 0
        uf = UnionFind(grid)
        for i in range(n):
            for j in range(m):
                if grid[i][j] == '1':
                    for k in range(4):
                        x,y = i+dx[k],j+dy[k]
                        if 0 <= x < n and 0 <= y < m and grid[x][y] == '1':
                            uf.union(i*m+j,x*m+y)
        return uf.cnt
    
class UnionFind:
    def __init__(self,grid):
        n,m = len(grid),len(grid[0])
        self.roots = [-1]*(m*n)
        self.cnt = 0
        self.rank = [0]*(m*n)
        for i in range(n):
            for j in range(m):
                if grid[i][j] == '1':
                    self.roots[i*m+j] = i*m+j
                    self.cnt += 1
                
    def find(self,i):
        while i != self.roots[i]:
            i = self.roots[i]
        return i
    
    def union(self,p,q):
        proot = self.find(p)
        qroot = self.find(q)
        if proot != qroot:
            if self.rank[proot] > self.rank[qroot]:
                self.roots[qroot] = proot
            elif self.rank[qroot] > self.rank[proot]:
                self.roots[proot] = qroot
            else:
                self.roots[qroot] = proot
                self.rank[proot] += 1
            self.cnt -= 1

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值