Open in App
Not now

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

• Difficulty Level : Basic
• Last Updated : 30 Mar, 2023

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 ` `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 > mat, ``int` `K,` `                          ``int` `src[], ``int` `dest[])` `{`   `    ``// Initialize a queue` `    ``queue 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 visited 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 > 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 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 visited 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 q = ``new` `Queue();`   `        ``// 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 visited 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

 ``

## Python3

 `# Python code for the above approach` `import` `queue`     `class` `Node:` `    ``def` `__init__(``self``, i, j, dist, val):` `        ``self``.i ``=` `i` `        ``self``.j ``=` `j` `        ``self``.dist ``=` `dist` `        ``self``.val ``=` `val` `# Function to find the length of the` `# shortest path with neighbor nodes` `# value not exceeding K`     `def` `shortest_path_less_than_k(mat, K, src, dest):` `    ``# Initialize a Queue` `    ``q ``=` `queue.Queue()` `    ``# Add the source Node` `    ``# into the queue` `    ``q.put(Node(src[``0``], src[``1``], ``0``, mat[src[``0``]][src[``1``]]))` `    ``# Initialize rows and columns` `    ``N ``=` `len``(mat)` `    ``M ``=` `len``(mat[``0``])` `    ``# Initialize a boolean matrix` `    ``# to keep track of visited cells` `    ``visited ``=` `[[``False` `for` `j ``in` `range``(M)] ``for` `i ``in` `range``(N)]`   `    ``dir` `=` `[[``-``1``, ``0``], [``1``, ``0``], [``0``, ``1``], [``0``, ``-``1``]]` `    ``while` `not` `q.empty():` `        ``curr ``=` `q.get()` `        ``# if already visited skip the rest` `        ``if` `visited[curr.i][curr.j]:` `            ``continue` `        ``# marking it as visited` `        ``visited[curr.i][curr.j] ``=` `True` `        ``# Return the answer after reaching dest node` `        ``if` `curr.i ``=``=` `dest[``0``] ``and` `curr.j ``=``=` `dest[``1``]:` `            ``return` `curr.dist` `        ``for` `i ``in` `range``(``4``):` `            ``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` `or` `y < ``0` `or` `x ``=``=` `N ``or` `y ``=``=` `M ``or` `visited[x][y] ``or` `abs``(curr.val ``-` `mat[x][y]) > K:` `                ``continue` `            ``# add current cell into the queue` `            ``q.put(Node(x, y, curr.dist ``+` `1``, mat[x][y]))` `    ``return` `-``1`     `mat ``=` `[[``-``1``, ``0``, ``4``, ``3``], [``6``, ``5``, ``7``, ``8``], [``2``, ``1``, ``2``, ``0``]]` `k ``=` `4` `src ``=` `[``0``, ``0``]` `dest ``=` `[``2``, ``3``]` `print``(shortest_path_less_than_k(mat, k, src, dest))`

Output

`7`

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

Another approach for above problem :

• Initialize a distance matrix to store the shortest distance from the source cell to each cell.
• Mark the source cell as visited and initialize its distance to 0.
• Initialize a priority queue to store the cells to be processed, and add the source cell to the priority queue.
• While the priority queue is not empty, pop the cell with the minimum distance from the priority queue.
• If the popped cell is the destination cell, return its distance.
• Explore the neighbors of the popped cell. If the difference between the neighbor node value and the current node value is less than or equal to K, calculate the distance to the neighbor cell and update the distance if it is shorter than the previously calculated distance. Add the neighbor cell to the priority queue.
• If the destination cell is not reachable from the source cell, return -1.

## Python3

 `import` `heapq`     `def` `shortest_path_less_than_k(mat, K, src, dest):` `    ``# Initialize rows and columns` `    ``N ``=` `len``(mat)` `    ``M ``=` `len``(mat[``0``])` `    ``# Initialize a distance matrix to store the shortest distance from src to each cell` `    ``dist ``=` `[[``float``(``'inf'``) ``for` `j ``in` `range``(M)] ``for` `i ``in` `range``(N)]` `    ``# Mark the source cell as visited and initialize its distance to 0` `    ``dist[src[``0``]][src[``1``]] ``=` `0` `    ``# Initialize a priority queue to store the cells to be processed` `    ``pq ``=` `[]` `    ``# Add the source cell to the priority queue` `    ``heapq.heappush(pq, (``0``, src[``0``], src[``1``], mat[src[``0``]][src[``1``]]))`   `    ``dir` `=` `[[``-``1``, ``0``], [``1``, ``0``], [``0``, ``1``], [``0``, ``-``1``]]` `    ``while` `pq:` `        ``# Pop the cell with the minimum distance from the priority queue` `        ``curr_dist, curr_i, curr_j, curr_val ``=` `heapq.heappop(pq)` `        ``# If the popped cell is the destination cell, return its distance` `        ``if` `curr_i ``=``=` `dest[``0``] ``and` `curr_j ``=``=` `dest[``1``]:` `            ``return` `curr_dist` `        ``# Explore the neighbors of the popped cell` `        ``for` `d ``in` `dir``:` `            ``i, j ``=` `curr_i ``+` `d[``0``], curr_j ``+` `d[``1``]` `            ``if` `i < ``0` `or` `i >``=` `N ``or` `j < ``0` `or` `j >``=` `M:` `                ``continue` `            ``neighbor_val ``=` `mat[i][j]` `            ``# If the difference between the neighbor node value and the current node value is less than or equal to K` `            ``if` `abs``(neighbor_val ``-` `curr_val) <``=` `K:` `                ``# Calculate the distance to the neighbor cell` `                ``neighbor_dist ``=` `curr_dist ``+` `1` `                ``# Update the distance if it is shorter than the previously calculated distance` `                ``if` `neighbor_dist < dist[i][j]:` `                    ``dist[i][j] ``=` `neighbor_dist` `                    ``# Add the neighbor cell to the priority queue` `                    ``heapq.heappush(pq, (neighbor_dist, i, j, neighbor_val))`   `    ``# If the destination cell is not reachable from the source cell, return -1` `    ``return` `-``1` `# code` `mat ``=` `[[``-``1``, ``0``, ``4``, ``3``], [``6``, ``5``, ``7``, ``8``], [``2``, ``1``, ``2``, ``0``]]` `k ``=` `4` `src ``=` `[``0``, ``0``]` `dest ``=` `[``2``, ``3``]` `print``(shortest_path_less_than_k(mat, k, src, dest))`

Output

`7`

Time Complexity: O(NM log(NM))
Auxiliary Space: O(NM)

My Personal Notes arrow_drop_up
Related Articles