Check if destination of given Matrix is reachable with required values of cells
Last Updated :
24 Mar, 2023
Given a matrix mat[][] of size N*M and the destination (x, y) to be reached from (0, 0), the task is to find if you can reach the destination following the given criteria:
- If the cell value is 0 you cannot move to that cell.
- If the cell value is 1, you can move to the cell and do not need to have any special value.
- In all other cases, you need to collect that value first before moving to that cell.
Movements in all four directions (up, down, left and right) are allowed and the positions where a specific value is situated are provided in a map name keys.
Input: mat = {{1, 0, 0, 0}, {1, 1, 1, 1}, {0, 2, 0, 0}, {1, 1, 1, 1}}
keys: {(1, 3): 2, (2, 1): 3}, x = 3, y = 1
Output: True
Explanation: In the above grid start from (0, 0) and
fetch the value 2 from (1, 3). Now move to (2, 1) and reach the destination (3, 1).
Input: mat = {{1, 0, 0, 0}, {1, 1, 1, 1}, {0, 2, 0, 0}, {1, 1, 2, 1}}
keys: {(1, 3)=> 2, (2, 1)=> 3}, x = 3, y = 3
Output: True
Approach: The way to solve the problem is based on the concept of BFS:
We need to collect the values of the special cells with values greater than 1, thus Breadth-first traversal can be used to explore the closest levels first and move in all directions to collect the values and find path to reach the destination.
Follow the steps mentioned below to implement the idea:
- Perform Breadth-first traversal in grid starting from (0, 0). Three cases can arise:
- Case 1 (When a cell has a value of 1): In this case, we simply push this coordinate in the queue for exploring.
- Case 2 (When a cell needs a special value that is already collected): The cells that require the value can now be pushed into the queue for processing.
- Case 3 (When a cell needs a special value that is not yet collected). In this case, push this cell into a map that represents the cells that cannot be traversed in the absence of a value. When the value is found while traversing the grid, then visit all the rooms that are stored in the map which require this value.
- If the target room (x, y) is reached then return true otherwise false.
Below is the complete implementation of the above idea:
C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Function to find if
// the destination can be reached or not
string Solvable(vector<vector<int> >& mat,
map<pair<int, int>, int> Given_keys,
int xDestination, int yDestination)
{
// Contains the keys which were found while
// traversing the grid.
set<int> ListOfAvailableKeys;
ListOfAvailableKeys.insert(1);
queue<vector<int> > q;
q.push({ 0, 0 });
vector<vector<int> > dirr{
{ 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 }
};
// Contains value -> ListOfCells which
// require this value.
unordered_map<int, vector<pair<int, int> > >
Unopened_Rooms;
while (!q.empty()) {
vector<int> curr = q.front();
q.pop();
// Checking if at the destination
if (curr[0] == xDestination
&& curr[1] == yDestination) {
return "True";
}
// Case 2: If the current co-ordinate
// contains any value.
if (Given_keys.find({ curr[0], curr[1] })
!= Given_keys.end()) {
int curr_key = Given_keys[{ curr[0], curr[1] }];
// Insert the found value in
// list of available values
ListOfAvailableKeys.insert(curr_key);
// Fetch the list of cells which require
// the current value and then
// push them in queue for exploration
for (int i = 0;
i < Unopened_Rooms[curr_key].size(); i++) {
q.push(
{ Unopened_Rooms[curr_key][i].first,
Unopened_Rooms[curr_key][i].second });
}
}
for (int i = 0; i < dirr.size(); i++) {
int x = curr[0] + dirr[i][0];
int y = curr[1] + dirr[i][1];
if (x < 0 || y < 0 || x >= mat.size()
|| y >= mat[0].size() || mat[x][y] == 0) {
continue;
}
// Case 3: if the cell requires a value
// that currently we don't have.
if (ListOfAvailableKeys.find(mat[x][y])
== ListOfAvailableKeys.end()) {
Unopened_Rooms[(mat[x][y])].push_back(
{ x, y });
// Mark the cell as visited.
mat[x][y] = 0;
}
else {
q.push({ x, y });
// Mark that cell as visited.
mat[x][y] = 0;
}
}
}
return "False";
}
// Driver Code
int main()
{
vector<vector<int> > mat{ { 1, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 2, 0, 0 },
{ 1, 1, 2, 1 } };
map<pair<int, int>, int> keys;
keys[{ 1, 1 }] = 3;
keys[{ 1, 3 }] = 2;
int x = 3, y = 3;
// Function Call
cout << Solvable(mat, keys, x, y);
return 0;
}
Python3
# Python3 code to implement the approach
# Function to find if
# the destination can be reached or not
def Solvable(mat, Given_keys, xDestination, yDestination):
# Contains the keys which were found while
# traversing the grid.
ListOfAvailableKeys = set()
ListOfAvailableKeys.add(1)
q = []
q.append([0, 0])
dirr = [[1, 0], [0, 1], [-1, 0], [0, -1]]
# Contains value -> ListOfCells which
# require this value.
Unopened_Rooms = {}
while (len(q)):
curr = q.pop(0)
# Checking if at the destination
if (curr[0] == xDestination and curr[1] == yDestination):
return "True"
# Case 2: If the current co-ordinate
# contains any value.
if ((curr[0], curr[1]) in Given_keys):
curr_key = Given_keys[(curr[0], curr[1])]
# Insert the found value in
# list of available values
ListOfAvailableKeys.add(curr_key)
# Fetch the list of cells which require
# the current value and then
# push them in queue for exploration
if curr_key in Unopened_Rooms:
for i in range(len(Unopened_Rooms[curr_key])):
q.append(
(Unopened_Rooms[curr_key][i][0], Unopened_Rooms[curr_key][i][1]))
for i in range(len(dirr)):
x = curr[0] + dirr[i][0]
y = curr[1] + dirr[i][1]
if (x < 0 or y < 0 or x >= len(mat) or y >= len(mat[0]) or mat[x][y] == 0):
continue
# Case 3: if the cell requires a value
# that currently we don't have.
if (mat[x][y] not in ListOfAvailableKeys):
if (mat[x][y] not in Unopened_Rooms):
Unopened_Rooms[(mat[x][y])] = []
Unopened_Rooms[(mat[x][y])].append([x, y])
# Mark the cell as visited.
mat[x][y] = 0
else:
q.append([x, y])
# Mark that cell as visited.
mat[x][y] = 0
return "False"
# Driver Code
mat = [[1, 0, 0, 0], [1, 1, 1, 1], [0, 2, 0, 0], [1, 1, 2, 1]]
keys = {}
keys[(1, 1)] = 3
keys[(1, 3)] = 2
x = 3
y = 3
# Function Call
print(Solvable(mat, keys, x, y))
# This code is contributed by phasing17
C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
class GFG {
// Function to find if
// the destination can be reached or not
static string Solvable(int[, ] mat,
Dictionary<string, int> Given_keys,
int xDestination, int yDestination)
{
// Contains the keys which were found while
// traversing the grid.
HashSet<int> ListOfAvailableKeys = new HashSet<int>();
ListOfAvailableKeys.Add(1);
List<int[]> q = new List<int[]>();
q.Add(new[] { 0, 0 });
int[, ] dirr = new int[, ] { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
// Contains value -> ListOfCells which
// require this value.
Dictionary<int, List<int[]> > Unopened_Rooms = new Dictionary<int, List<int[]> >();
while (q.Count > 0) {
int[] curr = q[0];
q.RemoveAt(0);
// Checking if at the destination
if (curr[0] == xDestination
&& curr[1] == yDestination) {
return "True";
}
// Case 2: If the current co-ordinate
// contains any value.
string key = Convert.ToString(curr[0]) + "#" + Convert.ToString(curr[1]);
if (Given_keys.ContainsKey(key)) {
int curr_key = Given_keys[key];
// Insert the found value in
// list of available values
ListOfAvailableKeys.Add(curr_key);
// Fetch the list of cells which require
// the current value and then
// push them in queue for exploration
if (Unopened_Rooms.ContainsKey(curr_key)) {
for (var i = 0;
i < Unopened_Rooms[curr_key].Count;
i++) {
q.Add(new[] {
Unopened_Rooms[curr_key][i][0],
Unopened_Rooms[curr_key][i][1] });
}
}
}
for (int i = 0; i < dirr.GetLength(0); i++) {
int x = curr[0] + dirr[i, 0];
int y = curr[1] + dirr[i, 1];
if (x < 0 || y < 0 || x >= mat.GetLength(0)
|| y >= mat.GetLength(1) || mat[x, y] == 0) {
continue;
}
// Case 3: if the cell requires a value
// that currently we don't have.
if (!ListOfAvailableKeys.Contains(mat[x, y])) {
if (!Unopened_Rooms.ContainsKey(
mat[x, y]))
Unopened_Rooms[(mat[x, y])] = new List<int[]>();
Unopened_Rooms[(mat[x, y])].Add(new[] { x, y });
// Mark the cell as visited.
mat[x, y] = 0;
}
else {
q.Add(new[] { x, y });
// Mark that cell as visited.
mat[x, y] = 0;
}
}
}
return "False";
}
// Driver Code
public static void Main(string[] args)
{
int[, ] mat = new[, ] { { 1, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 2, 0, 0 }, { 1, 1, 2, 1 } };
Dictionary<string, int> keys = new Dictionary<string, int>();
keys["1#1"] = 3;
keys["1#3"] = 2;
int x = 3;
int y = 3;
// Function Call
Console.WriteLine(Solvable(mat, keys, x, y));
}
}
// This code is contributed by phasing17
JavaScript
// JavaScript code to implement the approach
// Function to find if
// the destination can be reached or not
function Solvable(mat, Given_keys, xDestination,
yDestination)
{
// Contains the keys which were found while
// traversing the grid.
let ListOfAvailableKeys = new Set();
ListOfAvailableKeys.add(1);
let q = [];
q.push([ 0, 0 ]);
let dirr = [ [ 1, 0 ], [ 0, 1 ], [ -1, 0 ], [ 0, -1 ] ];
// Contains value -> ListOfCells which
// require this value.
let Unopened_Rooms = {};
while (q.length) {
let curr = q.shift();
// Checking if at the destination
if (curr[0] == xDestination
&& curr[1] == yDestination) {
return "True";
}
// Case 2: If the current co-ordinate
// contains any value.
if (Given_keys.hasOwnProperty(
[ curr[0], curr[1] ])) {
let curr_key
= Given_keys [[curr [0], curr [1]]];
// Insert the found value in
// list of available values
ListOfAvailableKeys.add(curr_key);
// Fetch the list of cells which require
// the current value and then
// push them in queue for exploration
if (Unopened_Rooms.hasOwnProperty(curr_key)) {
for (var i = 0;
i < Unopened_Rooms[curr_key].length;
i++) {
q.push([
Unopened_Rooms[curr_key][i][0],
Unopened_Rooms[curr_key][i][1]
]);
}
}
}
for (let i = 0; i < dirr.length; i++) {
let x = curr[0] + dirr[i][0];
let y = curr[1] + dirr[i][1];
if (x < 0 || y < 0 || x >= mat.length
|| y >= mat[0].length || mat[x][y] == 0) {
continue;
}
// Case 3: if the cell requires a value
// that currently we don't have.
if (!ListOfAvailableKeys.has(mat[x][y])) {
if (!Unopened_Rooms.hasOwnProperty(
mat[x][y]))
Unopened_Rooms[(mat[x][y])] = [];
Unopened_Rooms[(mat[x][y])].push([ x, y ]);
// Mark the cell as visited.
mat[x][y] = 0;
}
else {
q.push([ x, y ]);
// Mark that cell as visited.
mat[x][y] = 0;
}
}
}
return "False";
}
// Driver Code
let mat = [
[ 1, 0, 0, 0 ], [ 1, 1, 1, 1 ], [ 0, 2, 0, 0 ],
[ 1, 1, 2, 1 ]
];
let keys = {};
keys[[ 1, 1 ]] = 3;
keys[[ 1, 3 ]] = 2;
let x = 3;
let y = 3;
// Function Call
console.log(Solvable(mat, keys, x, y));
// This code is contributed by phasing17
Java
import java.util.*;
// java code to implement the approach
// Function to find if
// the destination can be reached or not
public class Solvable {
public static boolean
isSolvable(int[][] mat,
Map<List<Integer>, Integer> givenKeys,
int xDestination, int yDestination)
{
Set<Integer> listOfAvailableKeys = new HashSet<>();
listOfAvailableKeys.add(1);
Queue<List<Integer> > q = new LinkedList<>();
q.offer(Arrays.asList(0, 0));
int[][] dirr
= { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
// Contains value -> ListOfCells which
// require this value.
Map<Integer, List<List<Integer> > > unopenedRooms
= new HashMap<>();
while (!q.isEmpty()) {
List<Integer> curr = q.poll();
// Checking if at the destination
if (curr.get(0) == xDestination
&& curr.get(1) == yDestination) {
return true;
}
// Case 2: If the current co-ordinate
// contains any value.
if (givenKeys.containsKey(curr)) {
int currKey = givenKeys.get(curr);
// Insert the found value in
// list of available values
listOfAvailableKeys.add(currKey);
// Fetch the list of cells which require
// the current value and then
// push them in queue for exploration
if (unopenedRooms.containsKey(currKey)) {
for (List<Integer> room :
unopenedRooms.get(currKey)) {
q.offer(room);
}
}
}
for (int i = 0; i < dirr.length; i++) {
int x = curr.get(0) + dirr[i][0];
int y = curr.get(1) + dirr[i][1];
if (x < 0 || y < 0 || x >= mat.length
|| y >= mat[0].length
|| mat[x][y] == 0) {
continue;
}
// Case 3: if the cell requires a value
// that currently we don't have.
if (!listOfAvailableKeys.contains(
mat[x][y])) {
if (!unopenedRooms.containsKey(
mat[x][y])) {
unopenedRooms.put(
mat[x][y], new ArrayList<>());
}
unopenedRooms.get(mat[x][y]).add(
Arrays.asList(x, y));
// Mark the cell as visited.
mat[x][y] = 0;
}
else {
q.offer(Arrays.asList(x, y));
// Mark that cell as visited.
mat[x][y] = 0;
}
}
}
return false;
}
// Driver code
public static void main(String[] args)
{
int[][] mat = { { 1, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 2, 0, 0 },
{ 1, 1, 2, 1 } };
Map<List<Integer>, Integer> keys = new HashMap<>();
keys.put(Arrays.asList(1, 1), 3);
keys.put(Arrays.asList(1, 3), 2);
int x = 3;
int y = 3;
// Function call
System.out.println(isSolvable(mat, keys, x, y));
}
}
// This code is contributed by NarasingaNikhil
Time Complexity: O(N * M)
Auxiliary Space: O(1).
Similar Reads
Minimum cells required to reach destination with jumps equal to cell values
Given a m x n matrix mat[][] containing positive integers. The problem is to reach to the cell (m-1, n-1) from the cell (0, 0) by following the given constraints. From a cell (i, j) one can move 'exactly' a distance of 'mat[i][j]' to the right (in the same row) or to below (in the same column) only
12 min read
Check if a destination is reachable from source with two movements allowed | Set 2
Given a pair of coordinates (X1, Y1)(source) and (X2, Y2)(destination), the task is to check if it is possible to reach the destination form the source by the following movements from any cell (X, Y): (X + Y, Y)(X, Y + X) Note: All coordinates are positive and can be as large as 1018. Examples: Inpu
7 min read
Count of Reachable cells in Grid within given Left-Right moves
Given a grid of size N X M in which some cells are empty, and some have obstacles, the task is to find how many cells (including the starting cell) are reachable from cell (startRow, startCol) such that number of right moves allowed are R and number of left moves allowed are L. An obstacle and empty
12 min read
Check if destination is reachable by moving at most K step each time
Given a binary matrix grid[][] of size M*N where '0' represents a blocked cell and '1' represents a normal cell and a source (sx, sy) and destination (dx, dy). The task is to check if the destination is reachable from the source by moving at most K units of distance in a single step. Examples: Input
14 min read
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: 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]
8 min read
Check if it is possible to reach destination in even number of steps in an Infinite Matrix
Given a source and destination in a matrix[][] of infinite rows and columns, the task is to find whether it is possible to reach the destination from the source in an even number of steps. Also, you can only move up, down, left, and right. Examples: Input: Source = {2, 1}, Destination = {1, 4}Output
4 min read
Check if a path exists from start to end cell in given Matrix with obstacles in at most K moves
Given a positive integer K and a matrix grid of dimensions N * M consisting of characters '.' and '#', where '.' represents the unblocked cells and '#' represents the blocked cells, the task is to check if the bottom-right of the grid can be reached from the top-left cell of the matrix through unblo
9 min read
Count of all unique paths from given source to destination in a Matrix
Given a 2D matrix of size n*m, a source âsâ and a destination âdâ, print the count of all unique paths from given âsâ to âdâ. From each cell, you can either move only to the right or down. Examples: Input: arr[][] = { {1, 2, 3}, {4, 5, 6} }, s = {0, 0}, d = {1, 2}Output: 3Explanation: All possible p
4 min read
Number of cells in a matrix that satisfy the given condition
Given an N * N grid consisting of empty cells (denoted by '1') and obstacles (denoted by '0'), the task is to find the number of empty cells in which a mirror can be placed to view the east-side view of grid from the south-side. Examples: Input: mat[][] = { {1, 1, 1}, {1, 1, 0}, {1, 0, 1}} Output: 2
11 min read
Queries to check if a path made up of even numbers from source to destination exists in a Matrix
Given two arrays R[] and C[] consisting of N integers such that a matrix of dimensions N x N can be formed whose element at index (i, j) is given by (R[i] + C[j]) for all possible pairs from the two arrays. Given a matrix Queries[][] with each row representing a query of the type {A, B, X, Y}, the t
13 min read