Python程序:计算划分左上角和右下角单元格所需的墙壁数量


假设我们有一个二维二进制矩阵,其中0表示空单元格,1表示墙壁。我们必须找到需要变成墙壁的最小单元格数量,以便左上角单元格和右下角单元格之间没有路径。我们不能在左上角单元格和右下角单元格上放置墙壁。我们只能向左、向右、向上和向下移动,不能斜着移动。

因此,如果输入如下所示:

0000
0100
0110
0000

则输出为2。

0100
0100
0110
0010

为了解决这个问题,我们将遵循以下步骤:

  • R := 矩阵的行数,C := 矩阵的列数

  • visited := 一个新的集合

  • tin := 一个新的映射,low := 一个新的映射

  • timer := 0

  • bridge_pts := 一个新的集合

  • par := 一个新的映射

  • src := 一个(0, 0)对

  • tgt := 一个(R − 1, C − 1)对

  • 定义一个函数dfs()。它将接收v和parent作为参数。

  • 标记v为已访问

  • par[v] := parent,tin[v] := timer,low[v] := timer

  • timer := timer + 1

  • children := 0

  • 对于v的每个相邻节点to,执行以下操作:

    • 如果to与parent相同,则

      • 进行下一次迭代

    • 如果to已被访问,则

      • low[v] := low[v]和tin[to]中的最小值

    • 否则,

      • dfs(to, v)

      • low[v] := low[v]和low[to]中的最小值

      • 如果low[to] >= tin[v]且parent不为空,则

        • 将v添加到bridge_pts

      • children := children + 1

  • 如果parent为空且children > 1,则

    • 将v添加到bridge_pts

  • 定义一个函数bfs()。它将接收root作为参数。

  • Q := 一个双端队列,包含一个只有一个元素root的列表

  • visited := 一个新的集合,并最初插入root

  • 当Q不为空时,执行以下操作:

    • v := Q的最后一个元素,然后从Q中删除最后一个元素

    • 如果v与tgt相同,则

      • 返回True

    • 对于v的每个相邻节点w,执行以下操作:

      • 如果w未被访问,则

        • 标记w为已访问

        • 将w插入到Q的左侧

  • 返回False

  • 在主方法中执行以下操作:

  • dfs(src, null)

  • 如果tgt不在par中,则

    • 返回0

  • 对于bridge_pts中的每个(i, j)对,执行以下操作:

    • matrix[i, j] := 1

  • 如果bfs(src)为True,则

    • 返回2

  • 返回1

让我们看看下面的实现,以便更好地理解:

示例

在线演示

from collections import deque
class Solution:
   def solve(self, matrix):
      R = len(matrix)
      C = len(matrix[0])
      def get_neighbors(i, j):
         for ii, jj in ((i + 1, j), (i− 1, j), (i, j + 1), (i, j − 1)):
            if 0 <= ii < R and 0 <= jj < C and matrix[ii][jj] == 0:
               yield ii, jj
      visited = set()
      tin = {}
      low = {}
      timer = 0
      bridge_pts = set()
      par = {}
      src = (0, 0)
      tgt = (R− 1, C− 1)
      def dfs(v, parent):
         nonlocal timer
         visited.add(v)
         par[v] = parent
         tin[v] = timer
         low[v] = timer
         timer += 1
         children = 0
         for to in get_neighbors(*v):
            if to == parent:
               continue
            if to in visited:
               low[v] = min(low[v], tin[to])
            else:
               dfs(to, v)
               low[v] = min(low[v], low[to])
               if low[to] >= tin[v] and parent is not None:
                  bridge_pts.add(v)
               children += 1
               if parent is None and children > 1:
                  bridge_pts.add(v)
               def bfs(root):
                  Q = deque([root])
                  visited = set([root])
                  while Q:
                     v = Q.pop()
                     if v == tgt:
                        return True
                     for w in get_neighbors(*v):
                        if w not in visited:
                           visited.add(w)
                           Q.appendleft(w)
                  return False
               dfs(src, None)
               if tgt not in par:
                  return 0
               for i, j in bridge_pts:
                  matrix[i][j] = 1
               if bfs(src):
                  return 2
               return 1
ob = Solution()
matrix = [
   [0, 0, 0, 0],
   [0, 1, 0, 0],
   [0, 1, 1, 0],
   [0, 0, 0, 0],
]
print(ob.solve(matrix))

输入

[
   [0, 0, 0, 0],
   [0, 1, 0, 0],
   [0, 1, 1, 0],
   [0, 0, 0, 0],
]

输出

2

更新于:2020-12-26

浏览量:179

开启你的职业生涯

完成课程获得认证

开始学习
广告