给定具有不同字符的2D网格arr [] [] ,任务是检测其是否包含循环。
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.
例子:
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)}.
方法:想法是在网格上使用DFS遍历来检测其中的循环。步骤如下:
- 选择给定矩阵的每个单元格((0,0)至(N – 1,M – 1)),因为没有明确的循环位置。
- 如果存在一个循环,则该循环的所有单元格应具有相同的值,并且应将它们连接起来,并检查最后一个元素和第一个元素应形成一个循环(它们应具有不同的父代)。
- 采取一个布尔变量,该变量将存储函数isCycle()的结果,该结果分别为1或0 ,指示是否存在循环。如果函数返回1,则将ans变量切换为true,并中断循环,否则继续。
- 如果ans直到最后一个都没有标记,则打印否,否则打印是。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
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;
}
Java
// 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
Python3
# 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#
// 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
No
时间复杂度:O(N * M)
辅助空间: O(N * M)