Open In App

Shortest path with constraint in Matrix

Last Updated : 18 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// 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;
}


Java




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


Python3




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


C#




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);
    }
}


Javascript




// 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();


Output

4

Time complexity: O(N2
Auxiliary Space: O(N2)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads