Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Shortest path in a Matrix from top-left to bottom right-corner with neighbors exceeding at most K

  • Difficulty Level : Hard
  • Last Updated : 03 Dec, 2021

Given a matrix mat[][] and an integer K, the task is to find the length of the shortest path in a matrix from top-left to bottom right corner such that the difference between neighbor nodes does not exceed K.

Example:

Input: mat = {{-1, 0, 4, 3}, K = 4, src = {0, 0}, dest = {2, 3}
                      { 6, 5, 7, 8}, 
                      { 2, 1, 2, 0}}
Output: 7
Explanation: The only shortest path where the difference between neighbor nodes does not exceed K is: -1 -> 0 ->4 -> 7 ->5 ->1 ->2 ->0

Input: mat = {{-1, 0, 4, 3}, K = 5, src = {0, 0}, dest = {2, 3}
                      { 6, 5, 7, 8}, 
                      { 2, 1, 2, 0}}
Output: 5

 

Approach: The given problem can be solved using breadth-first-search. The idea is to stop exploring the path if the difference between neighbor nodes exceeds K. Below steps can be used to solve the problem:

  • Apply breadth-first-search on the source node and visit the neighbor’s nodes whose absolute difference between their values and the current node’s value is not greater than K
  • A boolean matrix is used to keep track of visited cells of the matrix
  • After reaching the destination node return the distance traveled.
  • If the destination node cant be reached then return -1

Below is the implementation of the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
    int dist, i, j, val;
 
    // Constructor
    Node(int x, int y, int d, int v)
    {
        i = x;
        j = y;
        dist = d;
        val = v;
    }
};
 
// Function to find the length of the
// shortest path with neighbor nodes
// value not exceeding K
int shortestPathLessThanK(vector<vector<int> > mat, int K,
                          int src[], int dest[])
{
 
    // Initialize a queue
    queue<Node*> q;
 
    // Add the source node
    // into the queue
    Node* Nw
        = new Node(src[0], src[1], 0, mat[src[0]][src[1]]);
    q.push(Nw);
 
    // Initialize rows and cols
    int N = mat.size(), M = mat[0].size();
 
    // Initialize a boolean matrix
    // to keep track of visisted cells
    bool visited[N][M];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            visited[i][j] = false;
        }
    }
 
    // Initialize the directions
    int dir[4][2]
        = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } };
 
    // Apply BFS
    while (!q.empty()) {
 
        Node* curr = q.front();
        q.pop();
 
        // If cell is already visited
        if (visited[curr->i][curr->j])
            continue;
 
        // Mark current node as visited
        visited[curr->i][curr->j] = true;
 
        // Return the answer after
        // reaching the destination node
        if (curr->i == dest[0] && curr->j == dest[1])
            return curr->dist;
 
        // Explore neighbors
        for (int i = 0; i < 4; i++) {
 
            int x = dir[i][0] + curr->i,
                y = dir[i][1] + curr->j;
 
            // If out of bounds or already visited
            // or difference in neighbor nodes
            // values is greater than K
            if (x < 0 || y < 0 || x == N || y == M
                || visited[x][y]
                || abs(curr->val - mat[x][y]) > K)
                continue;
 
            // Add current cell into the queue
            Node* n
                = new Node(x, y, curr->dist + 1, mat[x][y]);
            q.push(n);
        }
    }
 
    // No path exists return -1
    return -1;
}
 
// Driver function
int main()
{
   
  // Initialize the matrix
    vector<vector<int> > mat = { { -1, 0, 4, 3 },
                                 { 6, 5, 7, 8 },
                                 { 2, 1, 2, 0 } };
    int K = 4;
 
    // Source node
    int src[] = { 0, 0 };
 
    // Destination node
    int dest[] = { 2, 3 };
 
    // Call the function
    // and print the answer
    cout << (shortestPathLessThanK(mat, K, src, dest));
}
 
// This code is contributed by Potta Lokesh

Java




// Java implementation for the above approach
 
import java.io.*;
import java.util.*;
import java.lang.Math;
 
class GFG {
 
    static class Node {
 
        int dist, i, j, val;
 
        // Constructor
        public Node(int i, int j,
                    int dist, int val)
        {
            this.i = i;
            this.j = j;
            this.dist = dist;
            this.val = val;
        }
    }
 
    // Function to find the length of the
    // shortest path with neighbor nodes
    // value not exceeding K
    public static int shortestPathLessThanK(
        int[][] mat, int K, int[] src, int[] dest)
    {
 
        // Initialize a queue
        Queue<Node> q = new LinkedList<>();
 
        // Add the source node
        // into the queue
        q.add(new Node(src[0], src[1], 0,
                       mat[src[0]][src[1]]));
 
        // Initialize rows and cols
        int N = mat.length,
            M = mat[0].length;
 
        // Initialize a boolean matrix
        // to keep track of visisted cells
        boolean[][] visited = new boolean[N][M];
 
        // Initialize the directions
        int[][] dir = { { -1, 0 }, { 1, 0 },
                        { 0, 1 }, { 0, -1 } };
 
        // Apply BFS
        while (!q.isEmpty()) {
 
            Node curr = q.poll();
 
            // If cell is already visited
            if (visited[curr.i][curr.j])
                continue;
 
            // Mark current node as visited
            visited[curr.i][curr.j] = true;
 
            // Return the answer after
            // reaching the destination node
            if (curr.i == dest[0] && curr.j == dest[1])
                return curr.dist;
 
            // Explore neighbors
            for (int i = 0; i < 4; i++) {
 
                int x = dir[i][0] + curr.i,
                    y = dir[i][1] + curr.j;
 
                // If out of bounds or already visited
                // or difference in neighbor nodes
                // values is greater than K
                if (x < 0 || y < 0 || x == N
                    || y == M || visited[x][y]
                    || Math.abs(curr.val - mat[x][y]) > K)
                    continue;
 
                // Add current cell into the queue
                q.add(new Node(x, y, curr.dist + 1,
                               mat[x][y]));
            }
        }
 
        // No path exists return -1
        return -1;
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Initialize the matrix
        int[][] mat = { { -1, 0, 4, 3 },
                        { 6, 5, 7, 8 },
                        { 2, 1, 2, 0 } };
        int K = 4;
 
        // Source node
        int[] src = { 0, 0 };
 
        // Destination node
        int[] dest = { 2, 3 };
 
        // Call the function
        // and print the answer
        System.out.println(
            shortestPathLessThanK(mat, K, src, dest));
    }
}

C#




// C# implementation for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    class Node {
 
        public int dist, i, j, val;
 
        // Constructor
        public Node(int i, int j,
                    int dist, int val)
        {
            this.i = i;
            this.j = j;
            this.dist = dist;
            this.val = val;
        }
    }
 
    // Function to find the length of the
    // shortest path with neighbor nodes
    // value not exceeding K
    public static int shortestPathLessThanK(
        int[,] mat, int K, int[] src, int[] dest)
    {
 
        // Initialize a queue
        Queue<Node> q = new Queue<Node>();
 
        // Add the source node
        // into the queue
        q.Enqueue(new Node(src[0], src[1], 0,
                        mat[src[0],src[1]]));
 
        // Initialize rows and cols
        int N = mat.GetLength(0),
            M = mat.GetLength(1);
 
        // Initialize a bool matrix
        // to keep track of visisted cells
        bool[,] visited = new bool[N,M];
 
        // Initialize the directions
        int[,] dir = { { -1, 0 }, { 1, 0 },
                        { 0, 1 }, { 0, -1 } };
 
        // Apply BFS
        while (q.Count!=0) {
 
            Node curr = q.Peek();
            q.Dequeue();
 
            // If cell is already visited
            if (visited[curr.i,curr.j])
                continue;
 
            // Mark current node as visited
            visited[curr.i,curr.j] = true;
 
            // Return the answer after
            // reaching the destination node
            if (curr.i == dest[0] && curr.j == dest[1])
                return curr.dist;
 
            // Explore neighbors
            for (int i = 0; i < 4; i++) {
 
                int x = dir[i,0] + curr.i,
                    y = dir[i,1] + curr.j;
 
                // If out of bounds or already visited
                // or difference in neighbor nodes
                // values is greater than K
                if (x < 0 || y < 0 || x == N
                    || y == M || visited[x,y]
                    || Math.Abs(curr.val - mat[x,y]) > K)
                    continue;
 
                // Add current cell into the queue
                q.Enqueue(new Node(x, y, curr.dist + 1,
                               mat[x,y]));
            }
        }
 
        // No path exists return -1
        return -1;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
 
        // Initialize the matrix
        int[,] mat = { { -1, 0, 4, 3 },
                        { 6, 5, 7, 8 },
                        { 2, 1, 2, 0 } };
        int K = 4;
 
        // Source node
        int[] src = { 0, 0 };
 
        // Destination node
        int[] dest = { 2, 3 };
 
        // Call the function
        // and print the answer
        Console.WriteLine(
            shortestPathLessThanK(mat, K, src, dest));
    }
}
 
// This code is contributed by shikhasingrajput

Javascript




<script>
// Javascript code for the above approach
class Node {
 
  // Constructor
  constructor(x, y, d, v) {
    this.i = x;
    this.j = y;
    this.dist = d;
    this.val = v;
  }
};
 
// Function to find the length of the
// shortest path with neighbor nodes
// value not exceeding K
function shortestPathLessThanK(mat, K, src, dest) {
 
  // Initialize a queue
  let q = [];
 
  // Add the source node
  // into the queue
  let Nw = new Node(src[0], src[1], 0, mat[src[0]][src[1]]);
  q.unshift(Nw);
 
  // Initialize rows and cols
  let N = mat.length, M = mat[0].length;
 
  // Initialize a boolean matrix
  // to keep track of visisted cells
  let visited = new Array(N).fill(0).map(() => new Array(M).fill(0));
  for (let i = 0; i < N; i++) {
    for (let j = 0; j < M; j++) {
      visited[i][j] = false;
    }
  }
 
  // Initialize the directions
  let dir = [[-1, 0], [1, 0], [0, 1], [0, -1]];
 
  // Apply BFS
  while (q.length) {
 
    let curr = q[q.length - 1];
    q.pop();
 
    // If cell is already visited
    if (visited[curr.i][curr.j])
      continue;
 
    // Mark current node as visited
    visited[curr.i][curr.j] = true;
 
    // Return the answer after
    // reaching the destination node
    if (curr.i == dest[0] && curr.j == dest[1])
      return curr.dist;
 
    // Explore neighbors
    for (let i = 0; i < 4; i++) {
 
      let x = dir[i][0] + curr.i,
        y = dir[i][1] + curr.j;
 
      // If out of bounds or already visited
      // or difference in neighbor nodes
      // values is greater than K
      if (x < 0 || y < 0 || x == N || y == M
        || visited[x][y]
        || Math.abs(curr.val - mat[x][y]) > K)
        continue;
 
      // Add current cell into the queue
      let n
        = new Node(x, y, curr.dist + 1, mat[x][y]);
      q.unshift(n);
    }
  }
 
  // No path exists return -1
  return -1;
}
 
// Driver function
 
// Initialize the matrix
let mat = [[-1, 0, 4, 3], [6, 5, 7, 8], [2, 1, 2, 0]];
let K = 4;
 
// Source node
let src = [0, 0];
 
// Destination node
let dest = [2, 3];
 
// Call the function
// and print the answer
document.write(shortestPathLessThanK(mat, K, src, dest));
 
// This code is contributed by gfgking.
</script>
Output
7

Time Complexity: O(N * M)
Auxiliary Space: O(N * M)


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!