Skip to content
Related Articles

Related Articles

Shortest path from a source cell to a destination cell of a Binary Matrix through cells consisting only of 1s
  • Last Updated : 30 Mar, 2021

Given a binary matrix mat[][] of dimensions of N * M and pairs of integers src and dest representing source and destination cells respectively, the task is to find the shortest sequence of moves from the given source cell to the destination cell via cells consisting only of 1s. The allowed moves are moving a cell left (L), right (R), up (U), and down (D) (if exists). If no such path exists, then print “-1”. Otherwise, print the sequence of moves.

Examples:

Input: mat[][] = {{‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’}, {‘0’, ‘1’, ‘1’, ‘1’, ‘1’, ‘0’}, {‘0’, ‘1’, ‘0’, ‘1’, ‘1’, ‘1’}, {‘0’, ‘1’, ‘1’, ‘1’, ‘1’, ‘0’}, {‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’}}, src = {1, 2}, dest = {2, 4}
Output: LDDRRRU
Explanation:
Following sequence of moves starting from the source cell (1, 2) to the destination cell (2, 4) is the shortest path possible:
(1, 2) -> (1, 1) -> (2, 1) -> (3, 1) -> (3, 2) -> (3, 3) -> (3, 4) -> (2, 4)
start -> Left -> Down -> Down ->Right -> Right -> Right -> Up
Therefore, the resultant path is LDDRRRRU.

Input: mat[][] = {{‘0’, ‘1’, ‘0’, ‘1’}, {‘1’, ‘0’, ‘1’, ‘1’}, {‘1’, ‘1’, ‘1’, ‘1’}, {‘1’, ‘0’, ‘0’, ‘0’}}, src = {0, 3}, dest = {3, 0}
Output: DDLLLD

Approach: The given problem can be solved by performing BFS Traversal on the given matrix from the given source cell to the destination cell. 
Follow the steps below to solve the given problem:

  • Initialize a queue required to perform BFS Traversal on the given matrix.
  • Initialize a boolean matrix, say visited[N][M], used to check whether a given cell is visited or not. Initially, set all indices as false.
  • Initialize another matrix, say distance[N][M], that is used to store the shortest distance from the source node to each cell. Initialize it as -1.
  • Initialize a string pathMoves as “” to store the path from source to the destination cell.
  • Push the source node into the queue with the distance as 0.
  • Iterate until the queue is not empty and perform the following steps:
    • Pop the front node of the queue, say currentNode.
    • Check if the popped node is the destination node or not. If found to be true, then find the path from the destination cell to the source cell using Backtracking.
    • Otherwise, insert all the unvisited adjacent cells of the currently popped node with distance as (previous distance + 1). Update the value of distance[currentNode.x][currentNode.y] as (currentDistance + 1).
  • After completing the above steps, if the path exists from the given source to the destination cell, then print the path stored in pathMoves as the result. Otherwise, print “-1”.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
#define ROW 4
#define COL 4
 
// Stores the coordinates
// of the matrix cell
struct Point {
    int x, y;
};
 
// Stores coordinates of
// a cell and its distance
struct Node {
    Point pt;
    int dist;
};
 
// Check if the given cell is valid or not
bool isValid(int row, int col)
{
    return (row >= 0) && (col >= 0)
           && (row < ROW) && (col < COL);
}
 
// Stores the moves of the directions of adjacent cells
int dRow[] = { -1, 0, 0, 1 };
int dCol[] = { 0, -1, 1, 0 };
 
// Function to find the shortest path from the
// source to destination in the given  matrix
void pathMoves(char mat[][COL],
               Point src, Point dest)
{
    // Stores the distance for each
    // cell from the source cell
    int d[ROW][COL];
    memset(d, -1, sizeof d);
 
    // Distance of source cell is 0
    d[src.x][src.y] = 0;
 
    // Initialize a visited array
    bool visited[ROW][COL];
    memset(visited, false, sizeof visited);
 
    // Mark source cell as visited
    visited[src.x][src.y] = true;
 
    // Create a queue for BFS
    queue<Node> q;
 
    // Distance of source cell is 0
    Node s = { src, 0 };
 
    // Enqueue source cell
    q.push(s);
 
    // Keeps track of whether
    // destination is reached or not
    bool ok = false;
 
    // Iterate until queue is not empty
    while (!q.empty()) {
 
        // Deque front of the queue
        Node curr = q.front();
        Point pt = curr.pt;
 
        // If the destination cell is
        // reached, then find the path
        if (pt.x == dest.x
            && pt.y == dest.y) {
 
            int xx = pt.x, yy = pt.y;
            int dist = curr.dist;
 
            // Assign the distance of
            // destination to the
            // distance matrix
            d[pt.x][pt.y] = dist;
 
            // Stores the smallest path
            string pathmoves = "";
 
            // Iterate until source is reached
            while (xx != src.x
                   || yy != src.y) {
 
                // Append D
                if (xx > 0 && d[xx - 1][yy] == dist - 1) {
                    pathmoves += 'D';
                    xx--;
                }
 
                // Append U
                if (xx < ROW - 1
                    && d[xx + 1][yy]
                           == dist - 1) {
                    pathmoves += 'U';
                    xx++;
                }
 
                // Append R
                if (yy > 0 && d[xx][yy - 1] == dist - 1) {
                    pathmoves += 'R';
                    yy--;
                }
 
                // Append L
                if (yy < COL - 1
                    && d[xx][yy + 1]
                           == dist - 1) {
                    pathmoves += 'L';
                    yy++;
                }
                dist--;
            }
 
            // Reverse the backtracked path
            reverse(pathmoves.begin(),
                    pathmoves.end());
 
            cout << pathmoves;
            ok = true;
            break;
        }
 
        // Pop the start of queue
        q.pop();
 
        // Explore all adjacent directions
        for (int i = 0; i < 4; i++) {
            int row = pt.x + dRow[i];
            int col = pt.y + dCol[i];
 
            // If the current cell is valid
            // cell and can be traversed
            if (isValid(row, col)
                && (mat[row][col] == '1'
                    || mat[row][col] == 's'
                    || mat[row][col] == 'd')
                && !visited[row][col]) {
 
                // Mark the adjacent cells as visited
                visited[row][col] = true;
 
                // Enque the adjacent cells
                Node adjCell
                    = { { row, col }, curr.dist + 1 };
                q.push(adjCell);
 
                // Update the distance
                // of the adjacent cells
                d[row][col] = curr.dist + 1;
            }
        }
    }
 
    // If the destination
    // is not reachable
    if (!ok)
        cout << -1;
}
 
// Driver Code
int main()
{
    char mat[ROW][COL] = { { '0', '1', '0', '1' },
                           { '1', '0', '1', '1' },
                           { '0', '1', '1', '1' },
                           { '1', '1', '1', '0' } };
    Point src = { 0, 3 };
    Point dest = { 3, 0 };
 
    pathMoves(mat, src, dest);
 
    return 0;
}

Java




// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG{
 
static int ROW;
static int COL;
 
// Stores the coordinates
// of the matrix cell
static class Point
{
    int x, y;
    Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}
 
// Stores coordinates of
// a cell and its distance
static class Node
{
    Point pt;
    int dist;
 
    Node(Point p, int dist)
    {
        this.pt = p;
        this.dist = dist;
    }
}
 
// Check if the given cell is valid or not
static boolean isValid(int row, int col)
{
    return (row >= 0) && (col >= 0) &&
           (row < ROW) && (col < COL);
}
 
// Stores the moves of the directions
// of adjacent cells
static int dRow[] = { -1, 0, 0, 1 };
static int dCol[] = { 0, -1, 1, 0 };
 
// Function to find the shortest path from the
// source to destination in the given  matrix
static void pathMoves(char mat[][], Point src,
                      Point dest)
{
     
    // Stores the distance for each
    // cell from the source cell
    int d[][] = new int[ROW][COL];
    for(int dd[] : d)
        Arrays.fill(dd, -1);
 
    // Distance of source cell is 0
    d[src.x][src.y] = 0;
 
    // Initialize a visited array
    boolean visited[][] = new boolean[ROW][COL];
 
    // Mark source cell as visited
    visited[src.x][src.y] = true;
 
    // Create a queue for BFS
    ArrayDeque<Node> q = new ArrayDeque<>();
 
    // Distance of source cell is 0
    Node s = new Node(src, 0);
 
    // Enqueue source cell
    q.addLast(s);
 
    // Keeps track of whether
    // destination is reached or not
    boolean ok = false;
 
    // Iterate until queue is not empty
    while (!q.isEmpty())
    {
         
        // Deque front of the queue
        Node curr = q.removeFirst();
        Point pt = curr.pt;
 
        // If the destination cell is
        // reached, then find the path
        if (pt.x == dest.x && pt.y == dest.y)
        {
            int xx = pt.x, yy = pt.y;
            int dist = curr.dist;
 
            // Assign the distance of
            // destination to the
            // distance matrix
            d[pt.x][pt.y] = dist;
 
            // Stores the smallest path
            String pathmoves = "";
 
            // Iterate until source is reached
            while (xx != src.x || yy != src.y)
            {
                 
                // Append D
                if (xx > 0 &&
                    d[xx - 1][yy] == dist - 1)
                {
                    pathmoves += 'D';
                    xx--;
                }
 
                // Append U
                if (xx < ROW - 1 &&
                    d[xx + 1][yy] == dist - 1)
                {
                    pathmoves += 'U';
                    xx++;
                }
 
                // Append R
                if (yy > 0 &&
                    d[xx][yy - 1] == dist - 1)
                {
                    pathmoves += 'R';
                    yy--;
                }
 
                // Append L
                if (yy < COL - 1 &&
                    d[xx][yy + 1] == dist - 1)
                {
                    pathmoves += 'L';
                    yy++;
                }
                dist--;
            }
 
            // Print reverse the backtracked path
            for(int i = pathmoves.length() - 1;
                    i >= 0; --i)
                System.out.print(pathmoves.charAt(i));
                 
            ok = true;
            break;
        }
 
        // Pop the start of queue
        if (!q.isEmpty())
            q.removeFirst();
 
        // Explore all adjacent directions
        for(int i = 0; i < 4; i++)
        {
            int row = pt.x + dRow[i];
            int col = pt.y + dCol[i];
 
            // If the current cell is valid
            // cell and can be traversed
            if (isValid(row, col) &&
               (mat[row][col] == '1' ||
                mat[row][col] == 's' ||
                mat[row][col] == 'd') &&
                !visited[row][col])
            {
 
                // Mark the adjacent cells as visited
                visited[row][col] = true;
 
                // Enque the adjacent cells
                Node adjCell = new Node(
                    new Point(row, col), curr.dist + 1);
                q.addLast(adjCell);
 
                // Update the distance
                // of the adjacent cells
                d[row][col] = curr.dist + 1;
            }
        }
    }
 
    // If the destination
    // is not reachable
    if (!ok)
        System.out.println(-1);
}
 
// Driver Code
public static void main(String[] args)
{
    char mat[][] = { { '0', '1', '0', '1' },
                     { '1', '0', '1', '1' },
                     { '0', '1', '1', '1' },
                     { '1', '1', '1', '0' } };
 
    ROW = mat.length;
    COL = mat[0].length;
 
    Point src = new Point(0, 3);
    Point dest = new Point(3, 0);
 
    pathMoves(mat, src, dest);
}
}
 
// This code is contributed by Kingash

Python3




# Python3 program for the above approach
from collections import deque
 
# Stores the coordinates
# of the matrix cell
class Point:
    def __init__(self, xx, yy):
        self.x = xx
        self.y = yy
 
# Stores coordinates of
# a cell and its distance
class Node:
    def __init__(self, P, d):
        self.pt = P
        self.dist = d
 
# Check if the given cell is valid or not
def isValid(row, col):
    return (row >= 0) and (col >= 0) and (row < 4) and (col < 4)
 
# Stores the moves of the directions of adjacent cells
dRow = [-1, 0, 0, 1]
dCol = [0, -1, 1, 0]
 
# Function to find the shortest path from the
# source to destination in the given  matrix
def pathMoves(mat, src, dest):
   
    # Stores the distance for each
    # cell from the source cell
    d = [[ -1 for i in range(4)] for i in range(4)]
 
    # Distance of source cell is 0
    d[src.x][src.y] = 0
 
    # Initialize a visited array
    visited = [[ False for i in range(4)] for i in range(4)]
    # memset(visited, false, sizeof visited)
 
    # Mark source cell as visited
    visited[src.x][src.y] = True
 
    # Create a queue for BFS
    q = deque()
 
    # Distance of source cell is 0
    s = Node(src, 0)
 
    # Enqueue source cell
    q.append(s)
 
    # Keeps track of whether
    # destination is reached or not
    ok = False
 
    # Iterate until queue is not empty
    while (len(q)>0):
 
        # Deque front of the queue
        curr = q.popleft()
        pt = curr.pt
 
        # If the destination cell is
        # reached, then find the path
        if (pt.x == dest.x and pt.y == dest.y):
            xx, yy = pt.x, pt.y
            dist = curr.dist
 
            # Assign the distance of
            # destination to the
            # distance matrix
            d[pt.x][pt.y] = dist
 
            # Stores the smallest path
            pathmoves = ""
 
            # Iterate until source is reached
            while (xx != src.x or yy != src.y):
 
                # Append D
                if (xx > 0 and d[xx - 1][yy] == dist - 1):
                    pathmoves += 'D'
                    xx -= 1
 
                # Append U
                if (xx < 4 - 1 and d[xx + 1][yy] == dist - 1):
                    pathmoves += 'U'
                    xx += 1
 
                # Append R
                if (yy > 0 and d[xx][yy - 1] == dist - 1):
                    pathmoves += 'R'
                    yy -= 1
 
                # Append L
                if (yy < 4 - 1 and d[xx][yy + 1] == dist - 1):
                    pathmoves += 'L'
                    yy += 1
                dist -= 1
 
            # Reverse the backtracked path
            pathmoves =  pathmoves[::-1]
 
            print(pathmoves, end = "")
            ok = True
            break
 
        # Pop the start of queue
        # q.pop()
 
        # Explore all adjacent directions
        for i in range(4):
            row = pt.x + dRow[i]
            col = pt.y + dCol[i]
 
            # If the current cell is valid
            # cell and can be traversed
            if (isValid(row, col) and (mat[row][col] == '1' or mat[row][col] == 's' or mat[row][col] == 'd') and (not visited[row][col])):
                
                # Mark the adjacent cells as visited
                visited[row][col] = True
 
                # Enque the adjacent cells
                adjCell = Node( Point(row, col), curr.dist + 1)
                q.append(adjCell)
 
                # Update the distance
                # of the adjacent cells
                d[row][col] = curr.dist + 1
 
    # If the destination
    # is not reachable
    if (not ok):
        print(-1)
 
# Driver Code
if __name__ == '__main__':
    mat =[ ['0', '1', '0', '1'],
          [ '1', '0', '1', '1'],
          [ '0', '1', '1', '1'],
          [ '1', '1', '1', '0']]
 
    src = Point(0, 3)
    dest = Point(3, 0)
 
    pathMoves(mat, src, dest)
 
# This code is contributed by mohit kumar 29.

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
static int ROW;
static int COL;
 
// Stores the coordinates
// of the matrix cell
class Point
{
    public int x, y;
};
 
static Point newPoint(int x, int y)
{
    Point temp = new Point();
    temp.x = x;
    temp.y = y;
    return temp;
}
 
// Stores coordinates of
// a cell and its distance
class Node
{
    public Point pt;
    public int dist;
};
 
static Node newNode(Point p, int dist)
{
    Node temp = new Node();
    temp.pt = p;
    temp.dist = dist;
    return temp;
}
 
// Check if the given cell is valid or not
static bool isValid(int row, int col)
{
    return (row >= 0) && (col >= 0) &&
          (row < ROW) && (col < COL);
}
 
// Stores the moves of the directions
// of adjacent cells
static int []dRow = { -1, 0, 0, 1 };
static int []dCol = { 0, -1, 1, 0 };
 
// Function to find the shortest path from the
// source to destination in the given  matrix
static void pathMoves(char [,]mat, Point src,
                      Point dest)
{
     
    // Stores the distance for each
    // cell from the source cell
    int [,]d = new int[ROW, COL];
    for(int i = 0; i < ROW; i++)
    {
        for(int j = 0; j < COL; j++)
            d[i, j] = -1;
    }
 
    // Distance of source cell is 0
    d[src.x, src.y] = 0;
 
    // Initialize a visited array
    bool [,]visited = new bool[ROW, COL];
 
    // Mark source cell as visited
    visited[src.x, src.y] = true;
 
    // Create a queue for BFS
    Queue<Node> q = new Queue<Node>();
 
    // Distance of source cell is 0
    Node s = newNode(src, 0);
 
    // Enqueue source cell
    q.Enqueue(s);
 
    // Keeps track of whether
    // destination is reached or not
    bool ok = false;
 
    // Iterate until queue is not empty
    while (q.Count > 0)
    {
         
        // Deque front of the queue
        Node curr = q.Peek();
        q.Dequeue();
        Point pt = curr.pt;
 
        // If the destination cell is
        // reached, then find the path
        if (pt.x == dest.x && pt.y == dest.y)
        {
            int xx = pt.x, yy = pt.y;
            int dist = curr.dist;
 
            // Assign the distance of
            // destination to the
            // distance matrix
            d[pt.x,pt.y] = dist;
 
            // Stores the smallest path
            string pathmoves = "";
 
            // Iterate until source is reached
            while (xx != src.x || yy != src.y)
            {
                 
                // Append D
                if (xx > 0 &&
                  d[xx - 1, yy] == dist - 1)
                {
                    pathmoves += 'D';
                    xx--;
                }
 
                // Append U
                if (xx < ROW - 1 &&
                    d[xx + 1, yy] == dist - 1)
                {
                    pathmoves += 'U';
                    xx++;
                }
 
                // Append R
                if (yy > 0 &&
                    d[xx, yy - 1] == dist - 1)
                {
                    pathmoves += 'R';
                    yy--;
                }
 
                // Append L
                if (yy < COL - 1 &&
                    d[xx, yy + 1] == dist - 1)
                {
                    pathmoves += 'L';
                    yy++;
                }
                dist--;
            }
 
            // Print reverse the backtracked path
            for(int i = pathmoves.Length - 1;
                    i >= 0; --i)
                Console.Write(pathmoves[i]);
                 
            ok = true;
            break;
        }
 
        // Pop the start of queue
        if (q.Count > 0)
        {
            q.Peek();
            q.Dequeue();
        }
 
        // Explore all adjacent directions
        for(int i = 0; i < 4; i++)
        {
            int row = pt.x + dRow[i];
            int col = pt.y + dCol[i];
 
            // If the current cell is valid
            // cell and can be traversed
            if (isValid(row, col) &&
                   (mat[row, col] == '1' ||
                    mat[row, col] == 's' ||
                    mat[row, col] == 'd') &&
               !visited[row, col])
            {
                 
                // Mark the adjacent cells as visited
                visited[row,col] = true;
 
                // Enque the adjacent cells
                Node adjCell = newNode(newPoint(row, col),
                                       curr.dist + 1);
                q.Enqueue(adjCell);
 
                // Update the distance
                // of the adjacent cells
                d[row, col] = curr.dist + 1;
            }
        }
    }
 
    // If the destination
    // is not reachable
    if (ok == false)
        Console.Write(-1);
}
 
// Driver Code
public static void Main()
{
    char [,]mat = { { '0', '1', '0', '1' },
                    { '1', '0', '1', '1' },
                    { '0', '1', '1', '1' },
                    { '1', '1', '1', '0' } };
 
    ROW = mat.GetLength(0);
    COL = mat.GetLength(0);
 
    Point src = newPoint(0, 3);
    Point dest = newPoint(3, 0);
 
    pathMoves(mat, src, dest);
}
}
 
// This code is contributed by SURENDRA_GANGWAR
Output: 
DLDLDL

 

Time Complexity: O(N*M)
Auxiliary Space: O(N*M)




My Personal Notes arrow_drop_up
Recommended Articles
Page :