Open In App

Check if a valid path exists between given cells in a directional Matrix

Given a N x M matrix. Each cell of the matrix has a numerical value pointing to the next cell it leads to. The values of matrix[i][j] can be:

Source cell (x1, y1) and destination cell (x2, y2) are given. The task is to find whether a path exists between the given source cell and the destination cell.



Examples:

Input: matrix[][] = {{3, 2, 2, 2}, {3, 4, 2, 3}, {1, 3, 4, 4}, {2, 1, 1, 2}, {4, 4, 3, 3}}, source cell = {0, 3}, destination cell = {3, 1}
Output: Yes



3 2 2 2
3 4 2 3
1 3 4 4
2 1 1 2
4 4 3 3

Explanation : Starting from cell (0, 3), follow the path based on the direction rule. Traverse the cells in the following order: (0, 3)->(0, 2)->(0, 1)->(0, 0)->(1, 0)->(2, 0)->(2, 1)->(3, 1) which is the destination.

Input: matrix[][]={{1, 4, 3}, {2, 3, 2}, {4, 1, 4}}, source cell = {1, 1}, destination cell = {0, 3}
Output: No

1 4 3
2 3 2
4 1 4

Explanation: Starting from cell (1, 1), follow the path based on the direction rule. Traverse the cells as: (1, 1)->(2, 1)->(2, 2)->(1, 2)->(1, 1), here source cell is visited again and thus in any case destination cell is not visited.

 

Approach: The task can be solved by using either DFS or BFS.

Below is the implementation of the above approach:




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check whether a valid path
// exists or not
bool uniquepath(vector<vector<int> >& matrix, int curr_x,
                int curr_y, int dest_x, int dest_y,
                vector<vector<bool> >& visited)
{
    // Check if destination cell is reached
    if (curr_x == dest_x && curr_y == dest_y)
        return true;
 
    // Base Cases
    if (!(curr_x >= 0 && curr_x < matrix.size()
          && curr_y >= 0 && curr_y < matrix[0].size()))
        return false;
 
    // Check whether a visited cell is
    // re-visited again
    if (visited[curr_x][curr_y] == true)
        return false;
 
    // Mark current cell as visited
    visited[curr_x][curr_y] = true;
 
    // Moving based on direction rule
    if (matrix[curr_x][curr_y] == 1)
        return uniquepath(matrix, curr_x, curr_y + 1,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x][curr_y] == 2)
        return uniquepath(matrix, curr_x, curr_y - 1,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x][curr_y] == 3)
        return uniquepath(matrix, curr_x + 1, curr_y,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x][curr_y] == 4)
        return uniquepath(matrix, curr_x - 1, curr_y,
                          dest_x, dest_y, visited);
}
 
// Driver code
int main()
{
    vector<vector<int> > matrix = { { 3, 2, 2, 2 },
                                    { 3, 4, 2, 3 },
                                    { 1, 3, 4, 4 },
                                    { 2, 1, 1, 2 },
                                    { 4, 4, 1, 2 } };
    int start_x = 0, start_y = 3;
    int dest_x = 3, dest_y = 1;
    int n = matrix.size();
    int m = matrix[0].size();
    vector<vector<bool> > visited(
        n,
        vector<bool>(m, false));
    if (uniquepath(matrix, start_x, start_y,
                   dest_x, dest_y,
                   visited))
        cout << "Yes";
    else
        cout << "No";
}




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to check whether a valid path
// exists or not
static boolean uniquepath(int[][]matrix, int curr_x,
                          int curr_y, int dest_x,
                          int dest_y, boolean[][] visited)
{
     
    // Check if destination cell is reached
    if (curr_x == dest_x && curr_y == dest_y)
        return true;
 
    // Base Cases
    if (!(curr_x >= 0 && curr_x < matrix.length &&
          curr_y >= 0 && curr_y < matrix[0].length))
        return false;
 
    // Check whether a visited cell is
    // re-visited again
    if (visited[curr_x][curr_y] == true)
        return false;
 
    // Mark current cell as visited
    visited[curr_x][curr_y] = true;
 
    // Moving based on direction rule
    if (matrix[curr_x][curr_y] == 1)
        return uniquepath(matrix, curr_x, curr_y + 1,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x][curr_y] == 2)
        return uniquepath(matrix, curr_x, curr_y - 1,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x][curr_y] == 3)
        return uniquepath(matrix, curr_x + 1, curr_y,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x][curr_y] == 4)
        return uniquepath(matrix, curr_x - 1, curr_y,
                          dest_x, dest_y, visited);
                           
    return false;
}
 
// Driver code
public static void main(String[] args)
{
    int[][] matrix = { { 3, 2, 2, 2 },
                       { 3, 4, 2, 3 },
                       { 1, 3, 4, 4 },
                       { 2, 1, 1, 2 },
                       { 4, 4, 1, 2 } };
                        
    int start_x = 0, start_y = 3;
    int dest_x = 3, dest_y = 1;
    int n = matrix.length;
    int m = matrix[0].length;
     
    boolean[][] visited = new boolean[n][m];
    if (uniquepath(matrix, start_x, start_y,
                   dest_x, dest_y, visited))
        System.out.print("Yes");
    else
        System.out.print("No");
}
}
 
// This code is contributed by 29AjayKumar




# python program for the above approach
 
# Function to check whether a valid path
# exists or not
def uniquepath(matrix, curr_x, curr_y, dest_x, dest_y, visited):
 
    # Check if destination cell is reached
    if (curr_x == dest_x and curr_y == dest_y):
        return True
 
    # Base Cases
    if (not(curr_x >= 0 and curr_x < len(matrix) and curr_y >= 0 and curr_y < len(matrix[0]))):
        return False
 
    # Check whether a visited cell is
    # re-visited again
    if (visited[curr_x][curr_y] == True):
        return False
 
    # Mark current cell as visited
    visited[curr_x][curr_y] = True
 
    # Moving based on direction rule
    if (matrix[curr_x][curr_y] == 1):
        return uniquepath(matrix, curr_x, curr_y + 1, dest_x, dest_y, visited)
    elif (matrix[curr_x][curr_y] == 2):
        return uniquepath(matrix, curr_x, curr_y - 1, dest_x, dest_y, visited)
    elif (matrix[curr_x][curr_y] == 3):
        return uniquepath(matrix, curr_x + 1, curr_y, dest_x, dest_y, visited)
    elif (matrix[curr_x][curr_y] == 4):
        return uniquepath(matrix, curr_x - 1, curr_y, dest_x, dest_y, visited)
 
# Driver code
if __name__ == "__main__":
 
    matrix = [[3, 2, 2, 2],
              [3, 4, 2, 3],
              [1, 3, 4, 4],
              [2, 1, 1, 2],
              [4, 4, 1, 2]
              ]
    start_x = 0
    start_y = 3
    dest_x = 3
    dest_y = 1
    n = len(matrix)
    m = len(matrix[0])
    visited = [[False for _ in range(m)] for _ in range(n)]
    if (uniquepath(matrix, start_x, start_y, dest_x, dest_y, visited)):
        print("Yes")
    else:
        print("No")
 
    # This code is contributed by rakeshsahni




// C# program for the above approach
using System;
 
public class GFG{
 
// Function to check whether a valid path
// exists or not
static bool uniquepath(int[,]matrix, int curr_x,
                          int curr_y, int dest_x,
                          int dest_y, bool[,] visited)
{
     
    // Check if destination cell is reached
    if (curr_x == dest_x && curr_y == dest_y)
        return true;
 
    // Base Cases
    if (!(curr_x >= 0 && curr_x < matrix.GetLength(0) &&
          curr_y >= 0 && curr_y < matrix.GetLength(1)))
        return false;
 
    // Check whether a visited cell is
    // re-visited again
    if (visited[curr_x,curr_y] == true)
        return false;
 
    // Mark current cell as visited
    visited[curr_x,curr_y] = true;
 
    // Moving based on direction rule
    if (matrix[curr_x,curr_y] == 1)
        return uniquepath(matrix, curr_x, curr_y + 1,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x,curr_y] == 2)
        return uniquepath(matrix, curr_x, curr_y - 1,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x,curr_y] == 3)
        return uniquepath(matrix, curr_x + 1, curr_y,
                          dest_x, dest_y, visited);
    else if (matrix[curr_x,curr_y] == 4)
        return uniquepath(matrix, curr_x - 1, curr_y,
                          dest_x, dest_y, visited);
                           
    return false;
}
 
// Driver code
public static void Main(String[] args)
{
    int[,] matrix = { { 3, 2, 2, 2 },
                       { 3, 4, 2, 3 },
                       { 1, 3, 4, 4 },
                       { 2, 1, 1, 2 },
                       { 4, 4, 1, 2 } };
                        
    int start_x = 0, start_y = 3;
    int dest_x = 3, dest_y = 1;
    int n = matrix.GetLength(0);
    int m = matrix.GetLength(1);
     
    bool[,] visited = new bool[n,m];
    if (uniquepath(matrix, start_x, start_y,
                   dest_x, dest_y, visited))
        Console.Write("Yes");
    else
        Console.Write("No");
}
}
 
// This code is contributed by 29AjayKumar




<script>
// Javascript program for the above approach
 
// Function to check whether a valid path
// exists or not
function uniquepath(matrix, curr_x, curr_y, dest_x, dest_y, visited)
{
 
  // Check if destination cell is reached
  if (curr_x == dest_x && curr_y == dest_y) return true;
 
  // Base Cases
  if (
    !(
      curr_x >= 0 &&
      curr_x < matrix.length &&
      curr_y >= 0 &&
      curr_y < matrix[0].length
    )
  )
    return false;
 
  // Check whether a visited cell is
  // re-visited again
  if (visited[curr_x][curr_y] == true) return false;
 
  // Mark current cell as visited
  visited[curr_x][curr_y] = true;
 
  // Moving based on direction rule
  if (matrix[curr_x][curr_y] == 1)
    return uniquepath(matrix, curr_x, curr_y + 1, dest_x, dest_y, visited);
  else if (matrix[curr_x][curr_y] == 2)
    return uniquepath(matrix, curr_x, curr_y - 1, dest_x, dest_y, visited);
  else if (matrix[curr_x][curr_y] == 3)
    return uniquepath(matrix, curr_x + 1, curr_y, dest_x, dest_y, visited);
  else if (matrix[curr_x][curr_y] == 4)
    return uniquepath(matrix, curr_x - 1, curr_y, dest_x, dest_y, visited);
}
 
// Driver code
 
let matrix = [
  [3, 2, 2, 2],
  [3, 4, 2, 3],
  [1, 3, 4, 4],
  [2, 1, 1, 2],
  [4, 4, 1, 2],
];
let start_x = 0,
  start_y = 3;
let dest_x = 3,
  dest_y = 1;
let n = matrix.length;
let m = matrix[0].length;
 
let visited = new Array(n).fill(0).map(() => new Array(m).fill(false));
if (uniquepath(matrix, start_x, start_y, dest_x, dest_y, visited))
  document.write("Yes");
else document.write("No");
 
// This code is contributed by gfgking.
</script>

Output
Yes

Time Complexity: O(n*m)
Auxiliary Space: O(n*m)


Article Tags :