📜  在2D网格中检测周期

📅  最后修改于: 2021-05-17 18:09:24             🧑  作者: Mango

给定具有不同字符的2D网格arr [] [] ,任务是检测其是否包含循环。

例子:

方法:想法是在网格上使用DFS遍历来检测其中的循环。步骤如下:

  • 选择给定矩阵的每个单元格((0,0)至(N – 1,M – 1)),因为没有明确的循环位置。
  • 如果存在一个循环,则该循环的所有单元格应具有相同的值,并且应将它们连接起来,并检查最后一个元素和第一个元素应形成一个循环(它们应具有不同的父代)。
  • 采取一个布尔变量,该变量将存储函数isCycle()的结果,该结果分别为10 ,指示是否存在循环。如果函数返回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)