Program to check some elements in matrix forms a cycle or not in python


Suppose we have a 2d matrix. We have to check whether we can start from some cell then move adjacent cells (up, down, left, right) of the same value, and come back to the same starting point. We cannot revisit a cell that we have visited last.

So, if the input is like

2
2
2
1
2
1
2
1
2
2
2
1

then the output will be True, as we can follow 2s to form a cycle.

To solve this, we will follow these steps −

  • R := row count of matrix
  • C := column count of matrix
  • vis := make a matrix of size R x C and fill with False
  • Define a function dfs() . This will take root
  • stack := a stack with two elements root and null
  • vis[root[0], root[1]] := True
  • while stack is not empty, do
    • [v, prev] := top element of stack, and pop from stack
    • for each neighbor w of v, do
      • if w is not same as prev, then
        • if vis[w[0], w[1]] is false, then
          • vis[w[0], w[1]] := True
          • push [w, v] into stack
      • otherwise,
        • return True
  • return False
  • From the main method do the following:
  • for i in range 0 to R - 1, do
    • for j in range 0 to C - 1, do
      • if vis[i, j] is false, then
        • if dfs((i, j)) is true, then
          • return True
  • return False

Let us see the following implementation to get better understanding −

Example 

Live Demo

class Solution:
   def solve(self, matrix):
      R = len(matrix)
      C = len(matrix[0])

      def get_neighbors(i, j):
         val = matrix[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] == val:
               yield ii, jj

      vis = [[False] * C for _ in range(R)]

      def dfs(root):
         stack = [(root, None)]
         vis[root[0]][root[1]] = True
         while stack:
            v, prev = stack.pop()
            for w in get_neighbors(*v):
               if w != prev:
                  if not vis[w[0]][w[1]]:
                     vis[w[0]][w[1]] = True
                     stack.append((w, v))
                  else:
                     return True
         return False

      for i in range(R):
         for j in range(C):
            if not vis[i][j]:
               if dfs((i, j)):
                  return True
      return False
     
ob = Solution()
matrix = [
   [2, 2, 2, 1],
   [2, 1, 2, 1],
   [2, 2, 2, 1]
]
print(ob.solve(matrix))

Input

[  
[2, 2, 2, 1],  
[2, 1, 2, 1],  
[2, 2, 2, 1] ]

Output

True

Updated on: 03-Dec-2020

136 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements