zoukankan      html  css  js  c++  java
  • 433. 岛屿的个数

    433. 岛屿的个数

    中文English

    给一个 01 矩阵,求不同的岛屿的个数。

    0 代表海,1 代表岛,如果两个 1 相邻,那么这两个 1 属于同一个岛。我们只考虑上下左右为相邻。

    样例

    样例 1:

    输入:
    [
      [1,1,0,0,0],
      [0,1,0,0,1],
      [0,0,0,1,1],
      [0,0,0,0,0],
      [0,0,0,0,1]
    ]
    输出:
    3
    

    样例 2:

    输入:
    [
      [1,1]
    ]
    输出:
    1
    输入测试数据 (每行一个参数)如何理解测试数据?

    DFS写法(递归找寻当前岛屿所有关联的岛屿,赋值False)

     

    class Solution:
        """
        大致思路:
        1.主函数,循环grid,只要是True,就说明是新的岛屿,然后写一个dfs方法找寻该岛屿关联的所有岛屿
        """
        def numIslands(self, grid):
            # write your code here
            #dfs写法,递归找寻,一直关联查找
            if not grid: return 0
            
            len_x, len_y = len(grid), len(grid[0])
            count = 0 
            direction = [[0,1],[0,-1],[1,0],[-1,0]]
            
            #当前岛屿所关联的都会被找到,赋值False
            def dfs(x, y):
                #递归找寻,注意,当grid[x][y]是非岛屿的时候,也是不符合递归条件的
                if (x < 0 or y < 0 or x > len_x - 1 or y > len_y - 1 or not grid[x][y]):
                    return 
                
                #当前岛屿递归找寻
                grid[x][y] = False
                
                dfs(x + 1, y)
                dfs(x - 1, y)
                dfs(x, y + 1)
                dfs(x, y - 1)
                
            #主函数
            for i in range(len_x):
                for j in range(len_y):
                    if (grid[i][j]):
                        count += 1
                        #找寻该岛屿所关联的所有岛屿,都当做一个岛屿来看
                        dfs(i, j)
                        
            return count

    BFS写法(当前岛屿四周找寻符合条件的岛屿,一直不停的四周循环)

    class Solution:
        """
        @param grid: a boolean 2D matrix
        @return: an integer
        """
        def numIslands(self, grid):
            # write your code here
            #bfs写法,四周的找寻,放进队列里面,一直不停的找寻队列为岛屿的四周
            
            if not grid: return 0 
            
            len_x, len_y = len(grid), len(grid[0])
            count = 0 
            queue = []
            directon = [[1,0],[-1,0],[0,1],[0,-1]]
            
            def bfs(x, y):
                queue.append([x, y])
                
                while queue:
                    pop_num = queue.pop(0)
                    pop_x = pop_num[0]
                    pop_y = pop_num[1]
                    
                    #四周的找寻
                    for d in directon:
                        new_x = d[0] + pop_x 
                        new_y = d[1] + pop_y 
                        
                        #如果是这种情况,跳出处理
                        if (new_x < 0 or new_y < 0 or new_x > len_x - 1 or new_y > len_y - 1):
                            continue
                        
                        #否则判断是否是
                        if (grid[new_x][new_y]):
                            queue.append([new_x,new_y])
                            grid[new_x][new_y] = False 
            
            
            #主函数
            for i in range(len_x):
                for j in range(len_y):
                    if (grid[i][j]):
                        count += 1 
                        #当前岛屿四周不停的找寻符合条件的,赋值False
                        bfs(i, j)
            
            return count
            

    dfs会一直不停的找到当前该岛屿所关联的全部岛屿。而bfs只会找到当前岛屿的四周(上下左右),判断是否符合条件,不停的pop,append进行关联过去

    并查集(UnionFind)

    大致思路:当前节点判断是否和左上两个节点根节点相同,如果不同(一定不同,每个节点最开始指向自己),且相邻,说明是同一个岛屿 count -= 1

    如果左上没有True,则当前是新的岛屿,count不变。(判断,右下效果一样)

    class Solution:
        """
        @param grid: a boolean 2D matrix
        @return: an integer
        """
        def __init__(self):
            self.count = 0
            
        def numIslands(self, grid):
            # write your code here
            #并查集写法,每次需要考察右下两个方向的点,如果是相邻的点,则岛屿个数不加1
            #如果是相邻的两个点,则指向同一个根节点,相连
            if not grid: return 0
            
            #初始化
            len_x, len_y = len(grid), len(grid[0])
            father = {}
            for i in range(len_x):
                for j in range(len_y):
                    if grid[i][j]:
                        self.count += 1 
                        
                    cur = str(i) + 'and' + str(j)
                    father[cur] = cur 
        
            #
            def connect(num1, num2):
                root_num1 = unionfind(num1)
                root_num2 = unionfind(num2)
                
                if (root_num1 != root_num2):
                    father[root_num2] = root_num1
                    self.count -= 1 
                    
            
            def unionfind(num):
                orign_num = num
                if num == father[num]:
                    return num
                
                while num != father[num]:
                    num = father[num]
                
                #压缩路径
                while father[orign_num] != num:
                    temp = father[orign_num]
                    father[orign_num] = num
                    orign_num = temp
                
                return num
            
            for i in range(len_x):
                for j in range(len_y):
                    if (grid[i][j]):
                        cur = str(i) + 'and' + str(j)
                        if (i - 1 >= 0 and grid[i - 1][j]):
                            cur_new = str(i - 1) + 'and' + str(j)
                            connect(cur, cur_new)
                        if (j - 1 >= 0 and grid[i][j - 1]):
                            cur_new = str(i) + 'and' + str(j - 1)
                            connect(cur, cur_new)                    
            
            return self.count
                    
  • 相关阅读:
    Sharding-JDBC多数据源动态切换
    U 盘安装 CentOS 7 时出现 No Caching mode page found 问题的解决
    sudo 密码直接添加到命令行以方便实现脚本自动化
    Python3 Windows 虚拟环境的若干问题
    20 张图让你彻底弄懂 HTTPS 原理!
    全网写得最好的分库分表之 Sharding-JDBC 中间件介绍
    以为线程池很简单,结果第一道题就被干趴下了!
    以为线程池很简单,没想到第一问就被干趴下了
    分布式事务,看这篇就够了!
    我是一个线程池
  • 原文地址:https://www.cnblogs.com/yunxintryyoubest/p/13277222.html
Copyright © 2011-2022 走看看