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++ 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];
// Initially 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;
} |
// 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];
// Initially 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 |
# 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 |
// 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];
// Initially 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 |
<script> // Javascript program for the above approach
// Define size of grid
let N = 3;
let M = 4;
// To store direction of all the four
// adjacent cells
let directionInX = [ -1, 0, 1, 0 ];
let directionInY = [ 0, 1, 0, -1 ];
// Boolean function for checking
// if a cell is valid or not
function isValid(x, 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
function isCycle(x, y, arr, visited, parentX, parentY)
{
// Mark the current vertex true
visited[x][y] = true ;
// Loop for generate all possibilities
// of adjacent cells and checking them
for (let k = 0; k < 4; k++)
{
let newX = x + directionInX[k];
let 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
{
let 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
function detectCycle(arr)
{
// To store the visited cell
let visited = new Array(N);
// Initially marking all
// the cells as unvisited
for (let i = 0; i < N; i++)
{
visited[i] = new Array(M);
for (let j = 0; j < M; j++)
{
visited[i][j] = false ;
}
}
// Boolean variable for
// storing the result
let cycle = false ;
// As there is no fix position
// of Cycle we will have to
// check for every arr[i][j]
for (let i = 0; i < N; i++)
{
// If cycle is present and
// we have already detected
// it, then break this loop
if (cycle == true )
break ;
for (let 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 )
{
document.write( "Yes" );
}
// Cycle was not encountered
else
{
document.write( "No" );
}
}
// Given grid arr[][]
let arr = [ [ 'A ', ' A ', ' A ', ' A ' ],
[ ' A ', ' B ', ' C ', ' A ' ],
[ ' A ', ' D ', ' D ', ' A' ] ];
// Function call
detectCycle(arr);
// This code is contributed by divyeshrabadiy07. </script> |
No
Time Complexity: O(N * M)
Auxiliary Space: O(N * M)