zoukankan      html  css  js  c++  java
  • BFS-地图分析&岛屿数量

    1.地图分析

    解题思路
    此题是一个标准的广度优先题目。
    基本思路就是不断模拟从陆地向海洋扩张的最长距离:

      查找初始所有陆地坐标,并进行判断是否为空或长度与grid大小一致,满足条件即输出-1
        定义一个判断给定坐标值是否有效的辅助函数:isValid(x, y)
        定义一个4向delta列表,用于从当前坐标生成新坐标,并初始化depth=-1
        从当前陆地坐标列表开始向外扩张探索:
          对于每个待搜索的陆地坐标,依次生成4个方向新的坐标值
          若新坐标值尚未探索到,则加入到待探索列表tmp,并将其"填充"为陆地(即赋值为1),避免重复探索
          若当前深度所有陆地周边仍有待探索的海洋(即tmp不为空),则继续探测
    最后,需特殊考虑depth初值问题:由于陆地初始值是已有深度,当其探索一层后方可赋值为1,所以其初始值实际上应为-1.

    class Solution:
        def maxDistance(self, grid: List[List[int]]) -> int:
            # m-行数,n-列数
            m, n = len(grid), len(grid[0])
            # 找到陆地坐标
            nodes = [(i, j) for i in range(m) for j in range(n) if grid[i][j]]
            print(nodes)
    
            if not nodes or len(nodes)==m*n:#是否为纯陆地或纯海洋
               return -1
    
            # 判定指定坐标是否有效
            def isValid(x, y):
                return 0<=x<m and 0<=y<n
            
            # 四个移动方向
            delta = [(0, 1), (0, -1), (1, 0), (-1, 0)]
            depth = -1
            while nodes:
                depth += 1
                tmp = []  # 存储探索海洋目标
                for x, y in nodes: # 对当前每个待探坐标分别处理4个方向
                    for d in delta:
                        newx, newy = x+d[0], y+d[1]
                        if isValid(newx, newy) and not grid[newx][newy]:
                            tmp.append((newx, newy))
                            grid[newx][newy] = 1  # 已经探测到的改成陆地
                nodes = tmp
            return depth
    

      来看看细节:

    grid = [[1,0,1],[0,0,0],[1,0,1]]
    m, n = len(grid), len(grid[0])
    nodes = [(i, j) for i in range(m) for j in range(n) if grid[i][j]]
    print('nodes:', nodes)
    
    for x, y in nodes:
        print('x:', x)
        print('y:', y)
    

     

     

    class Solution:
        def numIslands(self, grid: List[List[str]]) -> int:
             # 方向数组,它表示了相对于当前位置的 4 个方向的横、纵坐标的偏移量,这是一个常见的技巧
            directions = [(-1, 0), (0, -1), (1, 0), (0, 1)]
            m = len(grid)
            # 特判
            if m == 0:
                return 0
            n = len(grid[0])
            marked = [[False for _ in range(n)] for _ 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()
                        queue.append((i, j))
                        # 注意:这里要标记上已经访问过
                        marked[i][j] = True
    
                        while queue:
                            cur_x, cur_y = queue.popleft()
                            for d in directions:
                                new_i, new_j = cur_x + d[0], cur_y + d[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
                        count += 1
            return count
    
    
                
    
                            
    

      以下是错误的,不知道为啥是错的

    class Solution:
        def numIslands(self, grid: List[List[str]]) -> int:
            m, n = len(grid), len(grid[0])
            # 找到陆地坐标
            nodes = [(i, j) for i in range(m) for j in range(n) if grid[i][j]]
            print(nodes)
    
            delta = [(0, 1), (0, -1), (1, 0), (-1, 0)]
            count = 0
            marked = [[False for _ in range(m)] for _ in range(n)]
            print(marked)
    
            while nodes:
                count += 1
                tmp = []
                for x, y in nodes:
                    for d in delta:
                        newx, newy = x+d[0], y+d[1]
                         # 只要是陆地,且没有被访问过的,就可以使用 BFS 发现与之相连的陆地,并进行标记
                        if 0<=m<newx and 0<=n<newy and not marked[newx][newy] and grid[newx][newy]:
                            tmp.append((newx, newy))
                            marked[newx][newy] = True
                nodes = tmp
            return count
    

      

     

  • 相关阅读:
    MyISAM 和InnoDB 区别 转
    beautifulsoup
    爬虫学习
    python操作数据库
    爬虫
    python爬虫
    PHP中“简单工厂模式”实例讲解
    PERL 实现微信登录
    PERL 实现微信登录
    NLS_LANG SIMPLIFIED CHINESE_CHINA.AL32UTF8 和american_america.AL32UTF8
  • 原文地址:https://www.cnblogs.com/GumpYan/p/13162190.html
Copyright © 2011-2022 走看看