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

  • 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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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!