Given an N x N matrix of positive integers. The task is to find the shortest path from the first cell of the matrix to its last cell that satisfies the given constraint. We are allowed to move exactly k steps from any cell in the matrix where k is the cell’s value, i.e., from a cell (i, j) having value k in a matrix M, we can move to ( i+k, j), ( i-k, j), ( i, j+k), or (i, j-k). Diagonal moves are not allowed.
Examples:
Input: N = 4
1 2 1 1
1 1 1 1
1 1 1 1
1 1 1 1
Output: 5
Approach: This can be solved with the following idea:
We can use the Breadth-First Search (BFS) algorithm to solve this problem. BFS is a graph traversal algorithm that visits all the vertices of a graph in breadth-first order, i.e., all the neighbors of a vertex is visited before visiting their neighbors.
Steps involved in the implementation of the code:
- Create a queue and add the source cell (0, 0) to it.
-
While the queue is not empty, do the following:
- Dequeue the front cell and check if it is the destination cell.
- If it is the destination cell, return its distance from the source.
- If not, for each possible move (i+k, j), (i-k, j), (i, j+k), or (i, j-k), check if the new cell is valid and not visited.
- If the new cell is valid and not visited, add it to the queue, mark it as visited, and update its distance from the source.
- If the destination cell is not reached, return -1.
Below is the implementation of the code:
// C++ code of the above approach #include <iostream> #include <queue> #include <utility> #include <vector> using namespace std;
// Function to check is coordinates valid bool isValid( int x, int y, int N)
{ return x >= 0 && x < N && y >= 0 && y < N;
} // Function to find shortest path from // first cell to last cell int shortestPath(vector<vector< int > >& matrix, int N)
{ vector<vector< bool > > visited(N,
vector< bool >(N, false ));
vector<vector< int > > distance(N, vector< int >(N, 0));
queue<pair< int , int > > q;
q.push({ 0, 0 });
visited[0][0] = true ;
// Start Iterating
while (!q.empty()) {
pair< int , int > cell = q.front();
q.pop();
int x = cell.first;
int y = cell.second;
int k = matrix[x][y];
if (x == N - 1 && y == N - 1) {
return distance[x][y];
}
int dx[] = { k, -k, 0, 0 };
int dy[] = { 0, 0, k, -k };
for ( int i = 0; i < 4; i++) {
int newX = x + dx[i];
int newY = y + dy[i];
// If coordinates are valid
if (isValid(newX, newY, N)
&& !visited[newX][newY]) {
q.push({ newX, newY });
visited[newX][newY] = true ;
distance[newX][newY] = distance[x][y] + 1;
}
}
}
return -1;
} // Driver code int main()
{ int N = 3;
vector<vector< int > > matrix
= { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
// Function call
int result = shortestPath(matrix, N);
cout << result << endl;
return 0;
} |
import java.util.LinkedList;
import java.util.Queue;
class Main {
// Function to check if coordinates are valid
static boolean isValid( int x, int y, int N)
{
return x >= 0 && x < N && y >= 0 && y < N;
}
// Function to find the shortest path from the first
// cell to the last cell
static int shortestPath( int [][] matrix, int N)
{
boolean [][] visited = new boolean [N][N];
int [][] distance = new int [N][N];
Queue< int []> queue = new LinkedList<>();
queue.offer( new int [] { 0 , 0 });
visited[ 0 ][ 0 ] = true ;
// Start Iterating
while (!queue.isEmpty()) {
int [] cell = queue.poll();
int x = cell[ 0 ];
int y = cell[ 1 ];
int k = matrix[x][y];
if (x == N - 1 && y == N - 1 ) {
return distance[x][y];
}
int [] dx = { k, -k, 0 , 0 };
int [] dy = { 0 , 0 , k, -k };
for ( int i = 0 ; i < 4 ; i++) {
int newX = x + dx[i];
int newY = y + dy[i];
// If coordinates are valid
if (isValid(newX, newY, N)
&& !visited[newX][newY]) {
queue.offer( new int [] { newX, newY });
visited[newX][newY] = true ;
distance[newX][newY]
= distance[x][y] + 1 ;
}
}
}
return - 1 ;
}
// Driver code
public static void main(String[] args)
{
int N = 3 ;
int [][] matrix
= { { 1 , 1 , 1 }, { 1 , 1 , 1 }, { 1 , 1 , 1 } };
// Function call
int result = shortestPath(matrix, N);
System.out.println(result);
}
} // This code is contributed by shivamgupta310570 |
from queue import Queue
# Function to check if coordinates are valid def is_valid(x, y, N):
return 0 < = x < N and 0 < = y < N
# Function to find the shortest path from the first cell to the last cell def shortest_path(matrix, N):
visited = [[ False for _ in range (N)] for _ in range (N)]
distance = [[ 0 for _ in range (N)] for _ in range (N)]
q = Queue()
q.put(( 0 , 0 ))
visited[ 0 ][ 0 ] = True
# Start Iterating
while not q.empty():
x, y = q.get()
k = matrix[x][y]
if x = = N - 1 and y = = N - 1 :
return distance[x][y]
dx = [k, - k, 0 , 0 ]
dy = [ 0 , 0 , k, - k]
for i in range ( 4 ):
new_x = x + dx[i]
new_y = y + dy[i]
# If coordinates are valid
if is_valid(new_x, new_y, N) and not visited[new_x][new_y]:
q.put((new_x, new_y))
visited[new_x][new_y] = True
distance[new_x][new_y] = distance[x][y] + 1
return - 1
# Driver code if __name__ = = "__main__" :
N = 3
matrix = [[ 1 , 1 , 1 ], [ 1 , 1 , 1 ], [ 1 , 1 , 1 ]]
# Function call
result = shortest_path(matrix, N)
print (result)
# This code is contributed by rambabuguphka
|
using System;
using System.Collections.Generic;
class MainClass
{ // Function to check if coordinates are valid
static bool isValid( int x, int y, int N)
{
return x >= 0 && x < N && y >= 0 && y < N;
}
// Function to find the shortest path from the first
// cell to the last cell
static int shortestPath( int [][] matrix, int N)
{
bool [,] visited = new bool [N, N];
int [,] distance = new int [N, N];
Queue< int []> queue = new Queue< int []>();
queue.Enqueue( new int [] { 0, 0 });
visited[0, 0] = true ;
// Start Iterating
while (queue.Count > 0)
{
int [] cell = queue.Dequeue();
int x = cell[0];
int y = cell[1];
int k = matrix[x][y];
if (x == N - 1 && y == N - 1)
{
return distance[x, y];
}
int [] dx = { k, -k, 0, 0 };
int [] dy = { 0, 0, k, -k };
for ( int i = 0; i < 4; i++)
{
int newX = x + dx[i];
int newY = y + dy[i];
// If coordinates are valid
if (isValid(newX, newY, N) && !visited[newX, newY])
{
queue.Enqueue( new int [] { newX, newY });
visited[newX, newY] = true ;
distance[newX, newY] = distance[x, y] + 1;
}
}
}
return -1;
}
// Driver code
public static void Main( string [] args)
{
int N = 3;
int [][] matrix =
{
new [] { 1, 1, 1 },
new [] { 1, 1, 1 },
new [] { 1, 1, 1 }
};
// Function call
int result = shortestPath(matrix, N);
Console.WriteLine(result);
}
} |
// Function to check if coordinates are valid function isValid(x, y, N) {
// Check if coordinates are within the matrix boundaries
return x >= 0 && x < N && y >= 0 && y < N;
} // Function to find the shortest path from the first cell to the last cell function shortestPath(matrix, N) {
// Initialize visited and distance arrays
const visited = Array.from({ length: N }, () => Array(N).fill( false ));
const distance = Array.from({ length: N }, () => Array(N).fill(0));
// Initialize queue with starting cell
const queue = [{ x: 0, y: 0 }];
visited[0][0] = true ;
// Start Iterating
while (queue.length > 0) {
// Process the front cell in the queue
const cell = queue.shift();
const x = cell.x;
const y = cell.y;
const k = matrix[x][y];
// Check if reached the destination
if (x === N - 1 && y === N - 1) {
return distance[x][y];
}
// Possible moves: right, left, down, up
const dx = [k, -k, 0, 0];
const dy = [0, 0, k, -k];
// Explore each possible move
for (let i = 0; i < 4; i++) {
const newX = x + dx[i];
const newY = y + dy[i];
// If coordinates are valid and not visited
if (isValid(newX, newY, N) && !visited[newX][newY]) {
// Enqueue the new cell
queue.push({ x: newX, y: newY });
// Mark the cell as visited
visited[newX][newY] = true ;
// Update the distance
distance[newX][newY] = distance[x][y] + 1;
}
}
}
// No valid path found
return -1;
} // Driver code function main() {
// Set matrix size
const N = 3;
// Define the matrix
const matrix = [
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]
];
// Function call
const result = shortestPath(matrix, N);
console.log(result);
} // Call the main function to execute the program main(); |
4
Time complexity: O(N2)
Auxiliary Space: O(N2)