Detect Cycle in a 2D grid

Given a 2D grid arr[][] with different characters, the task is to detect whether it contains a cycle or not.

A sequence of characters or integers c1, c2, …. cM  is called a cycle if and only if it meets the following condition:

  • M should at least be 4.
  • All characters belong to the same character or integer.  For all 0 <= i <= M -1 : ci and ci + 1 are adjacent.
  • Also, cM and c1 should also be adjacent that is they if they share a common edge.

Examples:

Input: arr[][] = {{‘A’, ‘A’, ‘A’, ‘A’},  



                         {‘A’, ‘B’, ‘C’, ‘A’},  

                        {‘A’, ‘D’, ‘D’, ‘A’}};
Output: No
Explanation:
There is no cycle in the above matrix as there is no such component which matches the requirements of being a cycle.

Input: arr[N][M] = {{‘A’, ‘A’, ‘A’, ‘A’},                                

                              {‘A’, ‘B’, ‘C’, ‘A’},                                

                              {‘A’, ‘A’, ‘A’, ‘A’}};

Output: Yes 
Explanation:
Cells mentioned below forms a cycle because all requirements are fulfilled.
{(0, 0), (0, 1), (0, 2), (0, 3),  (1, 0), (1, 3), (2, 0), (2, 1),  (2, 2), (2, 3)}.

Approach: The idea is to use DFS Traversal on the grid to detect a cycle in it. Below are the steps: 

  • Pick every cell of the given matrix ((0, 0) to (N – 1, M – 1)) because there is no definite position of the cycle.
  • If there exists a cycle, then all the cells of the cycle should have the same value, and they should be connected and also check that the last and the first element should form a loop (they should have different parents).
  • Take a boolean variable that will store the result of the function isCycle() which will be a 1 or 0 respectively, indicating whether there is a cycle or not. If the function returns 1, then switch the ans variable to true, and break the loop else continue.
  • If the ans remains unmarked till the last then print No otherwise print Yes.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach 
#include <bits/stdc++.h> 
using namespace std; 
  
// Define size of grid 
#define N 3 
#define M 4 
  
// To store direction of all the four 
// adjacent cells 
const int directionInX[4] = { -1, 0, 1, 0 }; 
const int directionInY[4] = { 0, 1, 0, -1 }; 
  
// Boolean function for checking 
// if a cell is valid or not 
bool isValid(int x, int y) 
    if (x < N && x >= 0 
        && y < M && y >= 0) 
        return 1; 
  
    return 0; 
  
// Boolean function which will check 
// whether the given array consist 
// of a cycle or not 
bool isCycle(int x, int y, char arr[N][M], 
            bool visited[N][M], 
            int parentX, int parentY) 
    // Mark the current vertex true 
    visited[x][y] = true
  
    // Loop for generate all possibilities 
    // of adjacent cells and checking them 
    for (int k = 0; k < 4; k++) { 
  
        int newX = x + directionInX[k]; 
        int newY = y + directionInY[k]; 
  
        if (isValid(newX, newY) == 1 
            && arr[newX][newY] == arr[x][y] 
            && !(parentX == newX 
                and parentY == newY)) { 
  
            // Check if there exist 
            // cycle then return true 
            if (visited[newX][newY] == 1) { 
  
                // Return 1 because the 
                // cycle exists 
                return true
            
  
            // Check if not found, 
            // keep checking recursively 
            else
                bool check 
                    = isCycle(newX, newY, arr, 
                            visited, x, y); 
  
                // Now, if check comes out 
                // to be true then return 1 
                // indicating there exist cycle 
                if (check == 1) 
                    return true
            
        
    
  
    // If there was no cycle, 
    // taking x and y as source 
    // then return false 
    return false
  
// Function to detect Cycle in a grid 
void detectCycle(char arr[N][M]) 
  
    // To store the visited cell 
    bool visited[N][M]; 
  
    // Intially marking all 
    // the cells as unvisited 
    for (int i = 0; i < N; i++) 
        for (int j = 0; j < M; j++) 
            visited[i][j] = false
  
    // Boolean variable for 
    // storing the result 
    bool cycle = 0; 
  
    // As there is no fix position 
    // of Cycle we will have to 
    // check for every arr[i][j] 
    for (int i = 0; i < N; i++) { 
  
        // If cycle is present and 
        // we have already detected 
        // it, then break this loop 
        if (cycle == true
            break
  
        for (int j = 0; j < M; j++) { 
  
            // Taking (-1, -1) as 
            // source node's parent 
            if (visited[i][j] == 0) { 
                cycle = isCycle(i, j, arr, 
                                visited, -1, -1); 
            
  
            // If we have encountered a 
            // cycle then break this loop 
            if (cycle == true
                break
        
    
  
    // Cycle was encountered 
    if (cycle == true) { 
        cout << "Yes"
    
  
    // Cycle was not encountered 
    else
        cout << "No"
    
  
// Driver code 
int main() 
    // Given grid arr[][] 
    char arr[N][M] = { { 'A', 'A', 'A', 'A' }, 
                    { 'A', 'B', 'C', 'A' }, 
                    { 'A', 'D', 'D', 'A' } }; 
  
    // Function Call 
    detectCycle(arr); 
    return 0; 
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach 
import java.util.*; 
  
class GFG{ 
  
// Define size of grid 
static final int N = 3
static final int M = 4
  
// To store direction of all the four 
// adjacent cells 
static int directionInX[] = new int[]{ -1, 0, 1, 0 }; 
static int directionInY[] = new int[]{ 0, 1, 0, -1 }; 
  
// Boolean function for checking 
// if a cell is valid or not 
static boolean isValid(int x, int y) 
    if (x < N && x >= 0 && 
        y < M && y >= 0
        return true
    else
        return false
  
  
// Boolean function which will check 
// whether the given array consist 
// of a cycle or not 
static boolean isCycle(int x, int y, char arr[][], 
                    boolean visited[][], 
                    int parentX, int parentY) 
      
    // Mark the current vertex true 
    visited[x][y] = true
  
    // Loop for generate all possibilities 
    // of adjacent cells and checking them 
    for(int k = 0; k < 4; k++) 
    
        int newX = x + directionInX[k]; 
        int newY = y + directionInY[k]; 
  
        if (isValid(newX, newY) == true && 
            arr[newX][newY] == arr[x][y] && 
            !(parentX == newX && parentY == newY)) 
        
              
            // Check if there exist 
            // cycle then return true 
            if (visited[newX][newY] == true
            
                  
                // Return 1 because the 
                // cycle exists 
                return true
            
  
            // Check if not found, 
            // keep checking recursively 
            else
            
                boolean check = isCycle(newX, newY, 
                                        arr, visited, 
                                        x, y); 
  
                // Now, if check comes out 
                // to be true then return 1 
                // indicating there exist cycle 
                if (check == true
                    return true
            
        
    
      
    // If there was no cycle, 
    // taking x and y as source 
    // then return false 
    return false
  
// Function to detect Cycle in a grid 
static void detectCycle(char arr[][]) 
      
    // To store the visited cell 
    boolean [][]visited = new boolean[N][M]; 
  
    // Intially marking all 
    // the cells as unvisited 
    for(int i = 0; i < N; i++) 
        for(int j = 0; j < M; j++) 
            visited[i][j] = false
  
    // Boolean variable for 
    // storing the result 
    boolean cycle = false
  
    // As there is no fix position 
    // of Cycle we will have to 
    // check for every arr[i][j] 
    for(int i = 0; i < N; i++) 
    
          
        // If cycle is present and 
        // we have already detected 
        // it, then break this loop 
        if (cycle == true
            break
  
        for(int j = 0; j < M; j++) 
        
              
            // Taking (-1, -1) as 
            // source node's parent 
            if (visited[i][j] == false
            
                cycle = isCycle(i, j, arr, 
                                visited, -1, -1); 
            
              
            // If we have encountered a 
            // cycle then break this loop 
            if (cycle == true
                break
        
    
  
    // Cycle was encountered 
    if (cycle == true
    
        System.out.print("Yes"); 
    
      
    // Cycle was not encountered 
    else
    
        System.out.print("No"); 
    
  
// Driver code 
public static void main(String[] args) 
      
    // Given grid arr[][] 
    char arr[][] = { { 'A', 'A', 'A', 'A' }, 
                    { 'A', 'B', 'C', 'A' }, 
                    { 'A', 'D', 'D', 'A' } }; 
  
    // Function call 
    detectCycle(arr); 
  
// This code is contributed by amal kumar choubey 

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
  
# Store direction of all the four 
# adjacent cells. We'll move along
# the grid using pairs of values
directionInX = [ -1, 0, 1, 0 ]
directionInY = [ 0, 1, 0, -1 ]
  
# Function for checking 
# if a cell is valid or not 
def isValid(x, y, N, M):
      
    if (x < N and x >= 0 and
        y < M and y >= 0):
        return True
          
    return False
  
# Function which will check whether
# the given array consist of a cycle or not 
def isCycle(x, y, arr, visited, parentX, parentY):
      
    # Mark the current vertex as visited
    visited[x][y] = True
      
    N, M = 3, 4
      
    # Loop for generate all possibilities 
    # of adjacent cells and checking them 
    for k in range(4):
        newX = x + directionInX[k]
        newY = y + directionInY[k]
          
        if (isValid(newX, newY, N, M) and 
            arr[newX][newY] == arr[x][y] and 
               not (parentX == newX and 
                    parentY == newY)):
                             
            # Check if there exist 
            # cycle then return true 
            if visited[newX][newY]:
                  
                # Return True as the
                # cycle exists
                return True
                  
            # If the cycle is not found 
            # then keep checking recursively
            else:
                check = isCycle(newX, newY, arr,
                                visited, x, y)
                if check:
                    return True
                      
    # If there was no cycle, taking 
    # x and y as source then return false
    return False
  
# Function to detect Cycle in a grid 
def detectCycle(arr):
      
    N, M = 3, 4
      
    # Initially all the cells are unvisited
    visited = [[False] * M for _ in range(N)]
  
    # Variable to store the result
    cycle = False
  
    # As there is no fixed position
    # of the cycle we have to loop 
    # through all the elements
    for i in range(N):
          
        # If cycle is present and 
        # we have already detected 
        # it, then break this loop
        if cycle == True:
            break
  
        for j in range(M):
              
            # Taking (-1, -1) as source
            # node's parent
            if visited[i][j] == False:
                cycle = isCycle(i, j, arr, 
                                visited, -1, -1)
              
            # If we have encountered a 
            # cycle then break this loop 
            if cycle == True:
                break
      
    # Cycle was encountered 
    if cycle == True:
        print("Yes")
          
    # Cycle was not encountered 
    else:
        print("No")
  
# Driver code
arr = [ [ 'A', 'A', 'A', 'A' ], 
        [ 'A', 'B', 'C', 'A' ], 
        [ 'A', 'D', 'D', 'A' ] ]
  
# Function call 
detectCycle(arr)
  
# This code is contributed by soum1071

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach 
using System; 
  
class GFG{ 
  
// Define size of grid 
static readonly int N = 3; 
static readonly int M = 4; 
  
// To store direction of all the four 
// adjacent cells 
static int []directionInX = new int[]{ -1, 0, 1, 0 }; 
static int []directionInY = new int[]{ 0, 1, 0, -1 }; 
  
// Boolean function for checking 
// if a cell is valid or not 
static bool isValid(int x, int y) 
    if (x < N && x >= 0 && 
        y < M && y >= 0) 
        return true
    else
        return false
  
// Boolean function which will check 
// whether the given array consist 
// of a cycle or not 
static bool isCycle(int x, int y, char [,]arr, 
                    bool [,]visited, 
                    int parentX, int parentY) 
      
    // Mark the current vertex true 
    visited[x, y] = true
  
    // Loop for generate all possibilities 
    // of adjacent cells and checking them 
    for(int k = 0; k < 4; k++) 
    
        int newX = x + directionInX[k]; 
        int newY = y + directionInY[k]; 
  
        if (isValid(newX, newY) == true && 
            arr[newX, newY] == arr[x, y] && 
            !(parentX == newX && parentY == newY)) 
        
              
            // Check if there exist 
            // cycle then return true 
            if (visited[newX, newY] == true
            
                  
                // Return 1 because the 
                // cycle exists 
                return true
            
  
            // Check if not found, 
            // keep checking recursively 
            else
            
                bool check = isCycle(newX, newY, 
                                    arr, visited, 
                                    x, y); 
  
                // Now, if check comes out 
                // to be true then return 1 
                // indicating there exist cycle 
                if (check == true
                    return true
            
        
    
      
    // If there was no cycle, 
    // taking x and y as source 
    // then return false 
    return false
  
// Function to detect Cycle in a grid 
static void detectCycle(char [,]arr) 
      
    // To store the visited cell 
    bool [,]visited = new bool[N, M]; 
  
    // Intially marking all 
    // the cells as unvisited 
    for(int i = 0; i < N; i++) 
        for(int j = 0; j < M; j++) 
            visited[i, j] = false
  
    // Boolean variable for 
    // storing the result 
    bool cycle = false
  
    // As there is no fix position 
    // of Cycle we will have to 
    // check for every arr[i,j] 
    for(int i = 0; i < N; i++) 
    
          
        // If cycle is present and 
        // we have already detected 
        // it, then break this loop 
        if (cycle == true
            break
  
        for(int j = 0; j < M; j++) 
        
              
            // Taking (-1, -1) as 
            // source node's parent 
            if (visited[i, j] == false
            
                cycle = isCycle(i, j, arr, 
                                visited, -1, -1); 
            
              
            // If we have encountered a 
            // cycle then break this loop 
            if (cycle == true
                break
        
    
  
    // Cycle was encountered 
    if (cycle == true
    
        Console.Write("Yes"); 
    
      
    // Cycle was not encountered 
    else
    
        Console.Write("No"); 
    
  
// Driver code 
public static void Main(String[] args) 
      
    // Given grid [,]arr 
    char [,]arr = { { 'A', 'A', 'A', 'A' }, 
                    { 'A', 'B', 'C', 'A' }, 
                    { 'A', 'D', 'D', 'A' } }; 
  
    // Function call 
    detectCycle(arr); 
  
// This code is contributed by amal kumar choubey 

chevron_right


Output: 

No

Time Complexity: O(N * M)
Auxiliary Space: O(N * M)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.