【问题标题】:Number of Islands problem. BFS solution is slow, trying to figure out the bottlenecks岛屿数量问题。 BFS 解决方案很慢,试图找出瓶颈
【发布时间】:2021-01-02 18:57:12
【问题描述】:

给定一个由“1”(陆地)和“0”(水)组成的 m x n 2d 网格图,返回岛屿的数量。

岛屿四面环水,由相邻陆地水平或垂直连接而成。您可以假设网格的所有四个边缘都被水包围。

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

我的解决方案:

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        no = 0 # number of islands
        visited = set()
        rows, cols = len(grid), len(grid[0])

        def visit(row, col):
            if (row, col) in visited or grid[row][col] != "1": return False

            q = deque()
            q.append((row, col))

            while q:
                row, col = q.popleft()
                if (row, col) in visited or grid[row][col] != "1": continue

                visited.add((row, col))

                # Visit left
                if col > 0:
                    q.append((row, col - 1))

                # Visit right
                if col < cols - 1: 
                    q.append((row, col + 1))

                # Visit top
                if row > 0:
                    q.append((row - 1, col))

                # Visit bottom
                if row < rows - 1: 
                    q.append((row + 1, col))

            return True

        for row in range(rows):
            for col in range(cols):
                if visit(row, col):
                    no += 1
        return no

它只优于约 40% 的解决方案,因此显然有一些可以改进的地方。它是什么?我错过了什么?

【问题讨论】:

    标签: python algorithm


    【解决方案1】:

    我很确定这是因为您要维护的访问集。这可以很容易地删除,因为您可以就地编辑矩阵以跟踪访问过的节点。

    1. 删除集合会缩短时间,因为不再对集合进行插入/删除/查找操作
    2. 您可以只为节点编号。就像用 -1 标记第一个岛中的所有节点,用 -2 标记第二个岛中的节点等一样。删除集合并使其更容易解决。

    【讨论】:

      【解决方案2】:

      您不需要用不同的数字对不同的岛屿进行分类。由于您只关心grid[row][col] 是否为“1”,因此在您访问每个岛屿后,只需将它们变为“0”,这样您就不会再次访问它们。

      从输入导入列表 从集合导入双端队列

      类解决方案: def 初始化(自我): self._directions=[[1,0],[-1,0],[0,1],[0,-1]]

      def numIslands(self,grid:List[List[int]])->int:
              ROWS,COLS=len(grid),len(grid[0])
              count=0
      
              for row in range(ROWS):
                  for col in range(COLS):
                      if grid[row][col]=="1":
                          count+=1
                          stack=deque()
                          stack.append([row,col])
                         # I found the first "1", I added to queue, and then make its value "0"
                          grid[row][col]="0"
                         # stack keeps all "1"s in the same island
                          while len(stack):
                              current=stack.popleft()
                              current_row=current[0]
                              current_col=current[1]
                              for direction in self._directions:
                                  new_row=current_row+direction[0]
                                  new_col=current_col+direction[1]
                                  if new_row<0 or new_row>=ROWS or new_col<0 or new_col>=COLS:
                                      continue
                                  if grid[new_row][new_col]=="1":
                                      stack.append([new_row,new_col])
                                      # I found another "1" in the same island, push it to stack and make its value "0"
                                      grid[new_row][new_col]="0"
              return count
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-30
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多