Count Walls Required to Partition Top-Left and Bottom-Right Cells in Python



Suppose we have a 2d binary matrix where 0 represents empty cell and 1 represents a wall. We have to find the minimum number cells that need to become walls so that there will be no path between top−left cell and bottom-right cell. We cannot put walls on the top−left cell and the bottom−right cell. We can move only left, right, up and down not diagonally.

So, if the input is like

0 0 0 0
0 1 0 0
0 1 1 0
0 0 0 0

then the output will be 2,

0 1 0 0
0 1 0 0
0 1 1 0
0 0 1 0

To solve this, we will follow these steps −

  • R := row count of matrix, C := column count of matrix

  • visited := a new set

  • tin := a new map, low := a new map

  • timer := 0

  • bridge_pts := a new set

  • par := a new map

  • src := a pair (0, 0)

  • tgt := a pair (R − 1, C − 1)

  • Define a function dfs() . This will take v, parent

  • mark v as visited

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

  • timer := timer + 1

  • children := 0

  • for each to neighbors of v, do

    • if to is same as parent, then

      • go for next iteration

    • if to is visited, then

      • low[v] := minimum of low[v] and tin[to]

    • otherwise,

      • dfs(to, v)

      • low[v] := minimum of low[v] and low[to]

      • if low[to] >= tin[v] and parent is not null, then

        • add v into bridge_pts

      • children := children + 1

  • if parent is null and children > 1, then

    • add v into bridge_pts

  • Define a function bfs() . This will take root

  • Q := a double ended queue with a list with single element root

  • visited := a new set and initially insert root

  • while Q is not empty, do

    • v := last element of Q, then delete last element from Q

    • if v is same as tgt, then

      • return True

    • for each w in the neighbors of v, do

      • if w is not visited, then

        • mark w as visited

        • insert w at the left of Q

  • return False

  • From the main method do the following −

  • dfs(src, null)

  • if tgt is not in par, then

    • return 0

  • for each pair (i, j) in bridge_pts, do

    • matrix[i, j] := 1

  • if bfs(src) is true, then

    • return 2

  • return 1

Let us see the following implementation to get better understanding −

Example

 Live Demo

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))

Input

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

Output

2
Updated on: 2020-12-26T10:31:50+05:30

195 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements