Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • 1 which means go to the cell to the right. (i.e. go from matrix[i][j] to matrix[i][j + 1])
  • 2 which means go to the cell to the left. (i.e. go from matrix[i][j] to matrix[i][j – 1])
  • 3 which means go to the lower cell. (i.e. go from matrix[i][j] to matrix[i + 1][j])
  • 4 which means go to the upper cell. (i.e. go from matrix[i][j] to matrix[i – 1][j])

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.

  • It can be observed that the path to be followed is fixed and we need to traverse the matrix based on the assigned direction rule.
  • Start either DFS or BFS from the source cell and move according to the direction rule described above.
  • If the destination cell is reached, a valid path is found.
  • If a visited cell is revisited again or the current cell’s indices goes out of the range, then the destination cell is not reached through that path, else continue.

Below is the implementation of the above approach:

C++




// 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




// 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


Python3




# 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#




// 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


Javascript




<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)



Last Updated : 10 Dec, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads