Program to count number of 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

0000
0100
0110
0000

then the output will be 2,

0100
0100
0110
0010

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: 26-Dec-2020

150 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements