Shortest Source to Destination Path | Practice | GeeksforGeeks

Given a 2D binary matrix A(0-based index) of dimensions NxM. Find the minimum number of steps required to reach from (0,0) to (X, Y).
Note: You can only move left, right, up and down, and only through cells that contain 1.
Example 1:
Input:
N=3
M=4
A=[[1,0,0,0], 
[1,1,0,1],[0,1,1,1]]
X=2
Y=3 
Output:
5
Explanation:
The shortest path is as follows:
(0,0)->(1,0)->(1,1)->(2,1)->(2,2)->(2,3).
Example 2:
Input:
N=3
M=4
A=[[1,1,1,1],
[0,0,0,1],[0,0,0,1]]
X=0
Y=3
Output:
3
Explanation:
The shortest path is as follows:
(0,0)->(0,1)->(0,2)->(0,3).

Your Task:
You don't need to read input or print anything. Your task is to complete the function shortestDistance() which takes the integer N, M, X, Y, and the 2D binary matrix A as input parameters and returns the minimum number of steps required to go from (0,0) to (X, Y).If it is impossible to go from (0,0) to (X, Y),then function returns -1. If value of the cell (0,0) is 0 (i.e  A[0][0]=0) then return -1.

Expected Time Complexity:O(N*M)
Expected Auxillary Space:O(N*M)
 
Constraints:
1 <= N,M <= 250
0 <= X < N
0 <= Y < M
0 <= A[i][j] <= 1
0
akshat0608002 days ago
//BFS Easy Solution
class Solution {
  public:
    int shortestDistance(int n, int m, vector<vector<int>> A, int x, int y) {
        queue<pair<int,int>> q;
        q.push({0,0});
        if(A[0][0]==0)
        return -1;
        vector<vector<int>> vis(n,vector<int> (m,0));
        int ans=0;
        while(!q.empty())
        {
            int s=q.size();
            while(s--)
            {int i=q.front().first;
            int j=q.front().second;q.pop();
            if(x==i&&j==y)
            return ans;
            if(i-1>=0&&vis[i-1][j]!=1&&A[i-1][j]==1)
            {
                vis[i-1][j]=1;
                q.push({i-1,j});
            }
            if(i+1<n&&vis[i+1][j]!=1&&A[i+1][j]==1)
            {
                vis[i+1][j]=1;
                q.push({i+1,j});
            }
            if(j-1>=0&&vis[i][j-1]!=1&&A[i][j-1]==1)
            {
                vis[i][j-1]=1;
                q.push({i,j-1});
            }
            if(j+1<m&&vis[i][j+1]!=1&&A[i][j+1]==1)
            {
                vis[i][j+1]=1;
                q.push({i,j+1});
            }}
            ans++;
        }
        return -1;
    }
};
0
bittubabusaha0073 weeks ago
class Solution {      static void convertMatrixToGraph(int [][]A,int N,int M,ArrayList<ArrayList<Integer>> graph){      for(int i=0;i<N;i++){            for(int j=0;j<M;j++){                if(A[i][j]==0)                continue;                                int nodeNumber=i*M+j;               //for up               if(i>0){                    if(A[i-1][j]==1){                        int neighbourNumber=(i-1)*M+j;                        graph.get(nodeNumber).add(neighbourNumber);                    }                }                //for down                if(i<N-1){                    if(A[i+1][j]==1){                        int neighbourNumber=(i+1)*M+j;                        graph.get(nodeNumber).add(neighbourNumber);                    }                }                //for right                if(j<M-1){                    if(A[i][j+1]==1){                        int neighbourNumber=(i)*M+j+1;                        graph.get(nodeNumber).add(neighbourNumber);                    }                }                //for left                if(j>0){                    if(A[i][j-1]==1){                        int neighbourNumber=(i)*M+j-1;                        graph.get(nodeNumber).add(neighbourNumber);                    }                }            }        }                }      static   int bfs( ArrayList<ArrayList<Integer>> graph,int sourceNode,int destinationNode){       int v=graph.size();       Queue<Integer> queue=new LinkedList<>();       int visited[]=new int[v];       int distance[]=new int[v];              for(int i=0;i<v;i++){          distance[i]=-1;        }              queue.add(sourceNode);       visited[sourceNode]=1;       distance[sourceNode]=0;              while(!queue.isEmpty()){           int currNode=queue.poll();                      for(int neighbour:graph.get(currNode)){               if(visited[neighbour]==0){                   distance[neighbour]=distance[currNode]+1;                   visited[neighbour]=1;                   queue.add(neighbour);               }           }       }              return distance[destinationNode];   }         int shortestDistance(int N, int M, int A[][], int X, int Y) {       // code here       int v=N*M;       ArrayList<ArrayList<Integer>> graph=new ArrayList<>();       for(int i=0;i<v;i++){           graph.add(new ArrayList<>());       }              if(A[0][0]==0 || A[X][Y]==0){           return -1;       }      convertMatrixToGraph(A,N,M,graph);             int destinationNode=X*M+Y;      return bfs(graph,0,destinationNode);   }}
+1
shyamprakash8073 weeks ago
Python solution :
Time Taken : 0.16/25.9
 
from collections import dequeclass Solution:   def shortestDistance(self,N,M,A,X,Y):       if A[0][0] == 0 or A[X][Y] == 0:           return -1       vis = [[False for i in range(M)] for j in range(N)]       vis[0][0] = True       q = deque()       # append x coordinate y coordinate and distance       q.append([0, 0, 0])       rownum = [-1, 0, 0, 1]       colnum = [0, -1, 1, 0]       def isValid(row, col):           return row>=0 and row<N and col>=0 and col<M       while len(q):           i, j, d = q.popleft()           if i == X and j == Y:               return d           for k in range(4):               row = i + rownum[k]               col = j + colnum[k]               if isValid(row, col) and A[row][col] == 1 and not vis[row][col]:                   vis[row][col] = True                   q.append([row, col, d+1])          return -1        
+1
19bcs13144 weeks ago
class Pair{
    int i,j;
    String path;
    Pair(String path,int i,int j){
        this.path=path;
        this.i=i;
        this.j=j;
    }
}

class Solution {
    
    boolean isValid(int[][] a,int x,int y,int r,int c,boolean[][] visit){
        if(x<0 || x>=r || y>=c || y<0 || a[x][y]==0 || visit[x][y]==true){
            return false;
        }
        return true;
    }
     
      int shortestDistance(int r, int c, int a[][], int x, int y) {
        // code here
        String ans="";
        boolean[][] visit=new boolean[r][c];
        if(x==0 && y==0 && a[0][0]==1) return 0;
        if(a[x][y]==0) return -1;
        if(a[0][0]!=1) return -1;
        
        Queue<Pair> q=new ArrayDeque<>();
        q.add(new Pair("",0,0));
        
        while(q.size()!=0){
            Pair temp=q.remove();
            int i=temp.i,j=temp.j;
            
            if(i==x && j==y){
                ans=temp.path;
                break;
            }
            if(isValid(a,i+1,j,r,c,visit)){
                q.add(new Pair(temp.path+"D",i+1,j));
                visit[i+1][j]=true;
            }
            if(isValid(a,i-1,j,r,c,visit)){
                q.add(new Pair(temp.path+"U",i-1,j));
                visit[i-1][j]=true;
            }
            if(isValid(a,i,j+1,r,c,visit)){
                q.add(new Pair(temp.path+"R",i,j+1));
                visit[i][j+1]=true;
            }
            if(isValid(a,i,j-1,r,c,visit)){
                q.add(new Pair(temp.path+"L",i,j-1));
                visit[i][j-1]=true;
            }

        }
       
        return ans.length()==0?-1:ans.length();
    }
};
+1
aniketg7214 weeks ago
Java Optimized, simple, easy to understand solution
class Solution {
    
    public void convertMatToGraph(int n, int m, int arr[][], ArrayList<ArrayList<Integer>> graph){
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                
                if(arr[i][j]==0){
                    continue;
                }
                int nodeNo= (i*m)+j;
                //check up
                if(i>0){
                    if(arr[i-1][j]==1){
                        int neighbourNo= (i-1)*m+j;
                        graph.get(nodeNo).add(neighbourNo);
                    }
                }
                //check down
                if(i<n-1){
                    if(arr[i+1][j]==1){
                        int neighbourNo= (i+1)*m+j;
                        graph.get(nodeNo).add(neighbourNo);
                    }
                }
                //check left
                if(j>0){
                    if(arr[i][j-1]==1){
                        int neighbourNo= (i*m)+j-1;
                        graph.get(nodeNo).add(neighbourNo);
                    }
                }
                //check right
                if(j<m-1){
                    if(arr[i][j+1]==1){
                        int neighbourNo= (i*m)+j+1;
                        graph.get(nodeNo).add(neighbourNo);
                    }
                }
            }
        }
    }
    
    public int bfs(ArrayList<ArrayList<Integer>> graph, int sourceNode, int destinationNo){
        int v= graph.size();
        Queue<Integer> q= new LinkedList<>();
        
        int[] visited= new int[v];
        int[] distance= new int[v];
        
        Arrays.fill(distance, -1);
        
        q.add(sourceNode);
        visited[sourceNode]=1;
        distance[sourceNode]=0;
        
        while(!q.isEmpty()){
            int currNode= q.poll();
            for(int neighbour : graph.get(currNode)){
                if(visited[neighbour]==0){
                    distance[neighbour]= distance[currNode]+1;
                    visited[neighbour]= 1;
                    q.add(neighbour);
                }
            }
        }
        return distance[destinationNo];
        
    }
    
    int shortestDistance(int n, int m, int arr[][], int x, int y) {
        if(arr[0][0]==0 || arr[x][y]==0){
            return -1;
        }
        ArrayList<ArrayList<Integer>> graph= new ArrayList<>();
        int v= n*m;
        for(int i=0; i<v; i++){
            graph.add(new ArrayList<>());
        }
        
        convertMatToGraph(n, m, arr, graph);
        
        int destinationNo= (x*m)+y;
        
        return bfs(graph, 0, destinationNo);
    }
}
0
aniketg721
This comment was deleted.
+1
bhaskarmaheshwari81 month ago
bool isSafe(int row,int col,vector<vector<int>>& A) {     int n=A.size();     int m=A[0].size();     if(row<0||col<0||row>n-1||col>m-1||A[row][col]==0)     return 0;     return 1; }   int shortestDistance(int n, int m, vector<vector<int>>& A, int X, int Y) {       // code here              // why to use bfs for this see strivers video from 18 to 19 min       // because bfs visits node at same level simultanewously       //refer https://www.youtube.com/watch?v=hwCWi7-bRfI              if(A[0][0]==0||A[X][Y]==0)       return -1;       queue<pair<pair<int,int>,int>> q;       vector<vector<int>> vis(n,vector<int>(m,0));       q.push({{0,0},0});       vis[0][0]=1;       while(!q.empty())       {          pair<pair<int,int>,int> p=q.front();           q.pop();                      int row=p.first.first;           int col=p.first.second;           if(X==row&&Y==col)           return p.second;           int dist=p.second;           int dx[]={-1,1,0,0};           int dy[]={0,0,-1,1};                      for(int i=0;i<4;i++)           {               if(isSafe(row+dx[i],col+dy[i],A)&&!vis[row+dx[i]][col+dy[i]])               {                   q.push({{row+dx[i],col+dy[i]},dist+1});                   vis[row+dx[i]][col+dy[i]]=1;               }           }       }              return -1;   }
-1
bhaskarmaheshwari81 month ago
This will not overflow int
 
bool isSafe(  vector<vector<int>> &A,  vector<vector<int>> &vis,int row,int col)   {       int n=A.size();       int m=A[0].size();       if(row<0||col<0||row>n-1||col>m-1||vis[row][col]||A[row][col]==0)       return 0;       return 1;   } void dfs(vector<vector<int>>& A,  vector<vector<int>> &vis,int row,int col,int x,int y,int ans,int &min_ans)   {   //refer https://www.techiedelight.com/find-shortest-path-in-maze/#:~:text=We%20can%20easily%20achieve%20this,the%20destination%20cell%20is%20reached.       if(row==x&&col==y)       {              min_ans=min(ans,min_ans);           return ;       }       vis[row][col]=1;       int dx[]={-1,1,0,0};       int dy[]={0,0,-1,1};          for(int i=0;i<4;i++)       {                                   if(isSafe(A,vis,row+dx[i],col+dy[i]))                dfs(A,vis,row+dx[i],col+dy[i],x,y,ans+1,min_ans);                      }       vis[row][col]=0;            }   int shortestDistance(int N, int M, vector<vector<int>> A, int X, int Y) {       // code here                 int n=A.size();          if(A[0][0]==0||A[X][Y]==0)          return -1;       int min_ans=INT_MAX;       vector<vector<int>> vis(n+1,vector<int>(n+1,0));       dfs(A,vis,0,0,X,Y,0,min_ans);                if(min_ans!=INT_MAX)        return min_ans;        return -1;   }
+1
bhaskarmaheshwari81 month ago
TLE but can also be done using dfs
 
bool isSafe(  vector<vector<int>> &A,  vector<vector<int>> &vis,int row,int col)   {       int n=A.size();       int m=A[0].size();       if(row<0||col<0||row>n-1||col>m-1||vis[row][col]||A[row][col]==0)       return 0;       return 1;   } int dfs(vector<vector<int>>& A,  vector<vector<int>> &vis,int row,int col,int x,int y)   {       if(row==x&&col==y)       {           return 0;       }       vis[row][col]=1;       int dx[]={-1,1,0,0};       int dy[]={0,0,-1,1};       int ans=INT_MAX/4;       for(int i=0;i<4;i++)       {           // for(int j=0;j<4;j++)           // {             // }                       if(isSafe(A,vis,row+dx[i],col+dy[i]))               ans=min(ans,1+dfs(A,vis,row+dx[i],col+dy[i],x,y));                      }       vis[row][col]=0;       return ans;   }   int shortestDistance(int N, int M, vector<vector<int>> A, int X, int Y) {       // code here                 int n=A.size();          if(A[0][0]==0||A[X][Y]==0)          return -1;              vector<vector<int>> vis(n+1,vector<int>(n+1,0));       int ans= dfs(A,vis,0,0,X,Y);       if(ans>=INT_MAX/4)       return -1;       return ans;   }
0
amrit_kumar1 month ago
c++ using structures
 struct node
    {
        int x;
        int y;
        int d;
    };
    bool valid(int x, int y, int N, int M, vector<vector<int>> &A)
    {
        return (x>=0&&y>=0&&x<N&&y<M&&A[x][y]==1);
    }
    int shortestDistance(int N, int M, vector<vector<int>> A, int X, int Y)
    {
        if(A[0][0]==0) return -1;
        int d = 0;
        int i,j;
        queue<node> q;
        struct node s = {0,0,0};
        q.push(s);
        A[0][0] = 0;
        
        while(!q.empty())
        {
            struct node temp = q.front();
            q.pop();
            i = temp.x;
            j = temp.y;
            d = temp.d;
            if(i==X&& j==Y) 
               return d;
            else 
                d++;
            if(valid(i-1,j,N,M,A))
            {
                q.push({i-1,j,d});
                A[i-1][j]=0;
            }
            if(valid(i+1,j,N,M,A))
            {
                q.push({i+1,j,d});
                A[i+1][j]=0;
            }
            if(valid(i,j-1,N,M,A))
            {
                q.push({i,j-1,d});
                A[i][j-1]=0;
            }
            if(valid(i,j+1,N,M,A))
            {
                q.push({i,j+1,d});
                A[i][j+1]=0;
            }
            
            
        }
        return -1;
    }
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.