LeetCode-Python-200. 岛屿的个数

644 篇文章 23 订阅

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

示例 1:

输入:
11110
11010
11000
00000

输出: 1

示例 2:

输入:
11000
11000
00100
00011

输出: 3

第一种思路:

DFS + visited数组保存去过的点。

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

        for i in range(m):
            for j in range(n):
                if M[i][j] == '1' and visited[i][j] == 0:
                    res += 1
                    visited[i][j] = 1
                    dfs(i, j)
                    # print visited
                    
        return res

第二种思路:

DFS + 染色,扫描输入,如果扫到“1”,就先把它变成“0”,然后递归地把跟它相连的点都变成“0”,

此题坑点在于LeetCode网站上输出会自动变成u"1", 解决办法是不要和“1”比,而是和“1”.encode("utf-8")做匹配。

# -*- coding: utf-8 -*-
class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        island = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == "1".encode('utf-8'):
                    print i,j
                    island += 1
                    self.checkNearbyIsland(grid, i, j)
                    # print island
        return island

    def checkNearbyIsland(self, grid, i, j):
        rows = len(grid)
        columns = len(grid[0])
        print i,j
        if i > rows - 1 or j > columns - 1 or i < 0 or j < 0 or grid[i][j] == "0".encode('utf-8'):
            return 
        
        if  grid[i][j] == "1".encode('utf-8'):
            grid[i][j] = "0"
            # print grid
            self.checkNearbyIsland(grid, i + 1, j)
            self.checkNearbyIsland(grid, i, j + 1)
            self.checkNearbyIsland(grid, i - 1, j)
            self.checkNearbyIsland(grid, i, j - 1)

第三种思路:

使用并查集。

# -*- coding: utf-8 -*-
class UnionFindSet(object):
    def __init__(self, grid):

        m, n = len(grid), len(grid[0])
        self.roots = [-1 for i in range(m*n)]
        self.rank = [0 for i in range(m*n)]
        self.count = 0
        
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '1':
                    self.roots[i * n + j] = i * n + j
                    self.count += 1
        
    def find(self, member):
        tmp = []
        while member != self.roots[member]:
            tmp.append(member)
            member = self.roots[member]
        for root in tmp:
            self.roots[root] = member
        return member
        
    def union(self, p, q):
        parentP = self.find(p)
        parentQ = self.find(q)
        if parentP != parentQ:
            if self.rank[parentP] > self.rank[parentQ]:
                self.roots[parentQ] = parentP
            elif self.rank[parentP] < self.rank[parentQ]:
                self.roots[parentP] = parentQ
            else:
                self.roots[parentQ] = parentP
                self.rank[parentP] -= 1
            self.count -= 1
   
class Solution(object):
    def numIslands(self, M):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not M or not M[0]:
            return 0
        
        dx = [1, -1, 0, 0]
        dy = [0, 0, 1, -1]
        
        ufs = UnionFindSet(M)
        m, n = len(M), len(M[0])
        
        for i in range(m):
            for j in range(n):
                if M[i][j] == '1':
                    
                    for k in range(4):
                        x = i + dx[k]
                        y = j + dy[k]
                        
                        if 0 <= x < m and 0 <= y < n and M[x][y] == '1':
                            ufs.union(i*n + j, x *n + y)
        # print ufs.roots
                            
        return ufs.count

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值