Open In App

Check if a path exists for a cell valued 1 to reach the bottom right corner of a Matrix before any cell valued 2

Improve
Improve
Like Article
Like
Save
Share
Report

Given a matrix arr[][] of dimensions N * M, having elements 0, 1, and 2. There is only one cell with value 1 present in the matrix. The task is to check if it is possible for 1 to reach the bottom right corner before any cell valued 2 or not using the following operations:

  • 2 can replicate itself 1 unit in all four directions in 1 unit of time.
  • 1 can only move in one direction among all four directions if the element at that position is 0.

Print “Yes” if a cell with value 1 will reach the bottom right corner in less than or equal amount of time than any cell with value 2. Otherwise, print “1″.

Examples:

Input: N = 3, M = 3, arr[][] = {{0, 2, 0}, {0, 1, 0}, {0, 0, 0}}
Output: Yes
Explanation:
1 can move to the bottom right corner in 2 moves and 2 can move to bottom right corner in 3 moves.
Since, cell with value 1 reaches first than the cell with value 2. Therefore, print Yes.

Input: N = 3, M = 3, arr[][] = {{0, 2, 0}, {0, 1, 0}, {0, 2, 0}}
Output: No
Explanation:
1 can move to the bottom right corner in 2 moves and 2 in the last row of the cell can move to bottom right corner in 1 moves.
Since, cell with value 2 reaches first than the cell with value 1. Therefore, print No.

Approach: The idea is to use a Multi-Source BFS. To perform multi-source BFS Traversal, add all the positions of 1 and 2s present in the matrix, in a Deque in the specified order. Perform the BFS on that dequeue by popping out the added positions and adding the adjacent positions that have not yet been visited. Follow the steps below to solve the problem:

  1. Create a dequeue for multi-source BFS.
  2. Firstly, add the position having 1 to the front and then add positions having 2 at the back. This is because if 1 and 2 reach the bottom right at the same time then 1 is considered over 2.
  3. Pop the elements from the front of the dequeue until the dequeue is empty and do the following: 
    • If the popped position is already visited, proceed to the next position.
    • If the position is not visited, check if it’s a bottom-right position or not as well as check if the element in it is 1 or not. If found to be true, then print Yes.
    • Otherwise, for all the four directions, insert the current positions in the dequeue.
  4. Once the above operations are exhausted, if the cell valued 1 is not found to have reached the bottom-right position, then print No.

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 if cell with
// value 1 doesn't reaches the bottom
// right cell or not
bool reachesBottom(vector<vector<int> >& a)
{
    // Number of rows and columns
    int n = a.size();
    int m = a[0].size();
 
    // Initialise the deque
    deque<vector<int> > q;
 
    // Traverse the matrix
    for (int i = 0; i < n; i++) {
 
        for (int j = 0; j < m; j++) {
 
            // Push 1 to front of queue
            if (a[i][j] == 1) {
                q.push_front({ i, j, 1 });
            }
 
            // Push 2 to back of queue
            else if (a[i][j] == 2) {
                q.push_back({ i, j, 2 });
            }
 
            a[i][j] = 0;
        }
    }
 
    // Store all the possible direction
    // of the current cell
    int dx[] = { -1, 0, 1, 0 };
    int dy[] = { 0, 1, 0, -1 };
 
    // Run multi-source BFS
    while (!q.empty()) {
 
        // Get the front element
        auto front = q.front();
 
        // Pop the front element
        q.pop_front();
 
        int i = front[0], j = front[1];
        int t = front[2];
 
        if (a[i][j])
            continue;
 
        a[i][j] = 1;
 
        // If 1 reached corner first
        if (t == 1 and (i == n - 1
                        && j == m - 1)) {
            return true;
        }
 
        for (int d = 0; d < 4; d++) {
            int ni = i + dx[d];
            int nj = j + dy[d];
 
            // Insert new point in queue
            if (ni >= 0 and ni < n
                and nj >= 0 and nj < m) {
                q.push_back({ ni, nj, t });
            }
        }
    }
 
    // If 1 can't reach the bottom
    // right then return false
    return false;
}
 
// Driver Code
int main()
{
    // Given matrix
    vector<vector<int> > matrix{ { 0, 2, 0 },
                                 { 0, 1, 0 },
                                 { 0, 2, 0 } };
 
    // Function Call
    if (reachesBottom(matrix)) {
        cout << "YES";
    }
    else {
        cout << "NO";
    }
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
import java.lang.*;
 
class GFG{
 
// Function to check if cell with
// value 1 doesn't reaches the bottom
// right cell or not
static boolean reachesBottom(int[][] a)
{
     
    // Number of rows and columns
    int n = a.length;
    int m = a[0].length;
 
    // Initialise the deque
    Deque<int[]> q = new LinkedList<>();
 
    // Traverse the matrix
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
 
            // Push 1 to front of queue
            if (a[i][j] == 1)
            {
                q.addFirst(new int[]{ i, j, 1 });
            }
 
            // Push 2 to back of queue
            else if (a[i][j] == 2)
            {
                q.addLast(new int[]{ i, j, 2 });
            }
            a[i][j] = 0;
        }
    }
 
    // Store all the possible direction
    // of the current cell
    int dx[] = { -1, 0, 1, 0 };
    int dy[] = { 0, 1, 0, -1 };
 
    // Run multi-source BFS
    while (!q.isEmpty())
    {
         
        // Get the front element
        int[] front = q.peekFirst();
 
        // Pop the front element
        q.removeFirst();
 
        int i = front[0], j = front[1];
        int t = front[2];
 
        if (a[i][j] == 1)
            continue;
 
        a[i][j] = 1;
 
        // If 1 reached corner first
        if (t == 1 && (i == n - 1 &&
                       j == m - 1))
        {
            return true;
        }
 
        for(int d = 0; d < 4; d++)
        {
            int ni = i + dx[d];
            int nj = j + dy[d];
 
            // Insert new point in queue
            if (ni >= 0 && ni < n &&
                nj >= 0 && nj < m)
            {
                q.addLast(new int[]{ ni, nj, t });
            }
        }
    }
 
    // If 1 can't reach the bottom
    // right then return false
    return false;
}
 
// Driver Code
public static void main (String[] args)
{
 
    // Given matrix
    int[][] matrix = { { 0, 2, 0 },
                       { 0, 1, 0 },
                       { 0, 2, 0 } };
                        
    // Function call
    if (reachesBottom(matrix))
    {
        System.out.print("YES");
    }
    else
    {
        System.out.print("NO");
    }
}
}
 
// This code is contributed by offbeat


Python3




# Python3 program for the above approach
from collections import deque
 
# Function to check if cell with
# value 1 doesn't reaches the bottom
# right cell or not
def reachesBottom(a):
     
    # Number of rows and columns
    n = len(a)
    m = len(a[0])
 
    # Initialise the deque
    q = deque()
 
    # Traverse the matrix
    for i in range(n):
        for j in range(m):
 
            # Push 1 to front of queue
            if (a[i][j] == 1):
                q.appendleft([i, j, 1])
 
            # Push 2 to back of queue
            elif (a[i][j] == 2):
                q.append([i, j, 2])
 
            a[i][j] = 0
 
    # Store all the possible direction
    # of the current cell
    dx = [ -1, 0, 1, 0 ]
    dy = [ 0, 1, 0, -1 ]
 
    # Run multi-source BFS
    while (len(q) > 0):
 
        # Get the front element
        front = q.popleft()
        i = front[0]
        j = front[1]
        t = front[2]
 
        if (a[i][j]):
            continue
 
        a[i][j] = 1
 
        # If 1 reached corner first
        if (t == 1 and (i == n - 1 and
                        j == m - 1)):
            return True
 
        for d in range(4):
            ni = i + dx[d]
            nj = j + dy[d]
 
            # Insert new point queue
            if (ni >= 0 and ni < n and
                nj >= 0 and nj < m):
                q.append([ni, nj, t])
 
    # If 1 can't reach the bottom
    # right then return false
    return False
 
# Driver Code
if __name__ == '__main__':
     
    # Given matrix
    matrix = [ [ 0, 2, 0 ],
               [ 0, 1, 0 ],
               [ 0, 2, 0 ] ]
 
    # Function call
    if (reachesBottom(matrix)):
        print("YES")
    else:
        print("NO")
 
# This code is contributed by mohit kumar 29


C#




// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to check if cell with
// value 1 doesn't reaches the bottom
// right cell or not
static bool reachesBottom(int [,]a,
                          int n, int m)
{
  // Initialise the deque
  Queue<int[]> q = new Queue<int[]>();
 
  // Traverse the matrix
  for(int i = 0; i < n; i++)
  {
    for(int j = 0; j < m; j++)
    {
      // Push 1 to front of queue
      if (a[i, j] == 1)
      {
        q.Enqueue(new int[]{i, j, 1});
      }
 
      // Push 2 to back of queue
      else if (a[i, j] == 2)
      {
        q.Enqueue(new int[]{i, j, 2});
      }
      a[i, j] = 0;
    }
  }
 
  // Store all the possible direction
  // of the current cell
  int []dx = {-1, 0, 1, 0};
  int []dy = {0, 1, 0, -1};
 
  // Run multi-source BFS
  while (q.Count != 0)
  {
    // Get the front element
    int[] front = q.Peek();
 
    // Pop the front element
    q.Dequeue();
 
    int i = front[0], j = front[1];
    int t = front[2];
 
    if (a[i, j] == 1)
      continue;
 
    a[i, j] = 1;
 
    // If 1 reached corner first
    if (t == 1 && (i == n - 1 &&
                   j == m - 1))
    {
      return true;
    }
 
    for(int d = 0; d < 4; d++)
    {
      int ni = i + dx[d];
      int nj = j + dy[d];
 
      // Insert new point in queue
      if (ni >= 0 && ni < n &&
          nj >= 0 && nj < m)
      {
        q.Enqueue(new int[]{ni, nj, t});
      }
    }
  }
 
  // If 1 can't reach the bottom
  // right then return false
  return false;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given matrix
  int[,] matrix = {{0, 2, 0},
                   {0, 1, 0},
                   {0, 2, 0}};
 
  // Function call
  if (reachesBottom(matrix, 3, 3))
  {
    Console.Write("YES");
  }
  else
  {
    Console.Write("NO");
  }
}
}
 
// This code is contributed by gauravrajput1


Javascript




<script>
 
// Javascript program for the above approach
 
// Function to check if cell with
// value 1 doesn't reaches the bottom
// right cell or not
function reachesBottom(a)
{
    // Number of rows and columns
    var n = a.length;
    var m = a[0].length;
 
    // Initialise the deque
    var q = [];
 
    // Traverse the matrix
    for (var i = 0; i < n; i++) {
 
        for (var j = 0; j < m; j++) {
 
            // Push 1 to front of queue
            if (a[i][j] == 1) {
                q.slice(0,0,[i, j, 1]);
            }
 
            // Push 2 to back of queue
            else if (a[i][j] == 2) {
                q.push([i, j, 2 ]);
            }
 
            a[i][j] = 0;
        }
    }
 
    // Store all the possible direction
    // of the current cell
    var dx = [-1, 0, 1, 0 ];
    var dy = [ 0, 1, 0, -1 ];
 
    // Run multi-source BFS
    while (!q.length) {
 
        // Get the front element
        var front = q[0];
 
        // Pop the front element
        q.shift();
 
        var i = front[0], j = front[1];
        var t = front[2];
 
        if (a[i][j])
            continue;
 
        a[i][j] = 1;
 
        // If 1 reached corner first
        if (t == 1 && (i == n - 1
                        && j == m - 1)) {
            return true;
        }
 
        for (var d = 0; d < 4; d++) {
            var ni = i + dx[d];
            var nj = j + dy[d];
 
            // Insert new point in queue
            if (ni >= 0 && ni < n
               && nj >= 0 && nj < m) {
                q.push([ ni, nj, t ]);
            }
        }
    }
 
    // If 1 can't reach the bottom
    // right then return false
    return false;
}
 
// Driver Code
// Given matrix
var matrix = [[ 0, 2, 0 ],
                             [ 0, 1, 0 ],
                             [0, 2, 0 ]];
// Function Call
if (reachesBottom(matrix)) {
    document.write( "YES");
}
else {
    document.write( "NO");
}
 
</script>


Output: 

NO

Time Complexity: O(N*M), The time complexity is O(N*M), where N is the number of rows and M is the number of columns in the given matrix. This is because the program traverses every cell of the matrix once to initialize the deque and again during the BFS traversal. In the worst case, all cells of the matrix may be traversed, resulting in O(N*M) time complexity.
Auxiliary Space: O(N*M), The space complexity of the program is also O(N*M). This is because the program initializes a deque to store all the possible directions of the current cell. In the worst case, the deque may store all the cells of the matrix, resulting in O(N*M) space complexity. Additionally, the program also initializes a 2D vector to represent the matrix, which also takes O(N*M) space. Therefore, the overall space complexity of the program is O(N*M).



Last Updated : 08 May, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads