Open In App

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

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:

Below is the implementation of the above approach:




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




# 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))




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




<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 visited 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)

Another approach for above problem :




#include<bits/stdc++.h>
using namespace std;
 
int shortest_path_less_than_k(vector<vector<int>>& mat, int K, vector<int>& src, vector<int>& dest)
{
    // Initialize rows and columns
    int N = mat.size();
    int M = mat[0].size();
    // Initialize a distance matrix to store the shortest distance from src to each cell
    vector<vector<int>> dist(N, vector<int>(M, INT_MAX));
    // 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
    priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> pq;
    // Add the source cell to the priority queue
    pq.push({0, src[0], src[1], mat[src[0]][src[1]]});
 
    vector<vector<int>> dir = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
    while (!pq.empty()) {
        // Pop the cell with the minimum distance from the priority queue
        vector<int> curr = pq.top();
        pq.pop();
        int curr_dist = curr[0];
        int curr_i = curr[1];
        int curr_j = curr[2];
        int curr_val = curr[3];
        // If the popped cell is the destination cell, return its distance
        if (curr_i == dest[0] && curr_j == dest[1]) {
            return curr_dist;
        }
        // Explore the neighbors of the popped cell
        for (auto& d : dir) {
            int i = curr_i + d[0];
            int j = curr_j + d[1];
            if (i < 0 || i >= N || j < 0 || j >= M) {
                continue;
            }
            int 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
                int 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
                    pq.push({neighbor_dist, i, j, neighbor_val});
                }
            }
        }
    }
 
    // If the destination cell is not reachable from the source cell, return -1
    return -1;
}
 
int main()
{
    vector<vector<int>> mat = {{-1, 0, 4, 3}, {6, 5, 7, 8}, {2, 1, 2, 0}};
    int k = 4;
    vector<int> src = {0, 0};
    vector<int> dest = {2, 3};
    cout << shortest_path_less_than_k(mat, k, src, dest) << endl;
    return 0;
}




/*package whatever //do not write package name here */
import java.util.*;
 
public class Main {
    public static int shortestPathLessThanK(int[][] mat,
                                            int K,
                                            int[] src,
                                            int[] dest)
    {
        // Initialize rows and columns
        int N = mat.length;
        int M = mat[0].length;
        // Initialize a distance matrix to store the
        // shortest distance from src to each cell
        int[][] dist = new int[N][M];
        for (int[] row : dist) {
            Arrays.fill(row, Integer.MAX_VALUE);
        }
        // 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
        PriorityQueue<int[]> pq
            = new PriorityQueue<>((a, b) -> a[0] - b[0]);
        // Add the source cell to the priority queue
        pq.offer(new int[] { 0, src[0], src[1],
                             mat[src[0]][src[1]] });
 
        int[][] dir
            = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } };
        while (!pq.isEmpty()) {
            // Pop the cell with the minimum distance from
            // the priority queue
            int[] curr = pq.poll();
            int curr_dist = curr[0];
            int curr_i = curr[1];
            int curr_j = curr[2];
            int curr_val = curr[3];
            // If the popped cell is the destination cell,
            // return its distance
            if (curr_i == dest[0] && curr_j == dest[1]) {
                return curr_dist;
            }
            // Explore the neighbors of the popped cell
            for (int[] d : dir) {
                int i = curr_i + d[0];
                int j = curr_j + d[1];
                if (i < 0 || i >= N || j < 0 || j >= M) {
                    continue;
                }
                int 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 (Math.abs(neighbor_val - curr_val)
                    <= K) {
                    // Calculate the distance to the
                    // neighbor cell
                    int 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
                        pq.offer(
                            new int[] { neighbor_dist, i, j,
                                        neighbor_val });
                    }
                }
            }
        }
 
        // If the destination cell is not reachable from the
        // source cell, return -1
        return -1;
    }
 
    public static void main(String[] args)
    {
        int[][] mat = { { -1, 0, 4, 3 },
                        { 6, 5, 7, 8 },
                        { 2, 1, 2, 0 } };
        int k = 4;
        int[] src = { 0, 0 };
        int[] dest = { 2, 3 };
        System.out.println(
            shortestPathLessThanK(mat, k, src, dest));
    }
}




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




using System;
using System.Collections.Generic;
 
class Program
{
    static int ShortestPathLessThanK(List<List<int>> mat, int K, List<int> src, List<int> dest)
    {
        // Initialize rows and columns
        int N = mat.Count;
        int M = mat[0].Count;
        // Initialize a distance matrix to store the shortest distance from src to each cell
        int[][] dist = new int[N][];
        for (int i = 0; i < N; i++)
        {
            dist[i] = new int[M];
            for (int j = 0; j < M; j++)
            {
                dist[i][j] = int.MaxValue;
            }
        }
        // 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
        var pq = new PriorityQueue<int[]>(
            (a, b) => a[0].CompareTo(b[0])
        );
        // Add the source cell to the priority queue
        pq.Enqueue(new int[] { 0, src[0], src[1], mat[src[0]][src[1]] });
 
        int[][] dir = { new int[] { -1, 0 }, new int[] { 1, 0 }, new int[] { 0, 1 }, new int[] { 0, -1 } };
        while (pq.Count > 0)
        {
            // Pop the cell with the minimum distance from the priority queue
            int[] curr = pq.Dequeue();
            int curr_dist = curr[0];
            int curr_i = curr[1];
            int curr_j = curr[2];
            int curr_val = curr[3];
            // If the popped cell is the destination cell, return its distance
            if (curr_i == dest[0] && curr_j == dest[1])
            {
                return curr_dist;
            }
            // Explore the neighbors of the popped cell
            foreach (var d in dir)
            {
                int i = curr_i + d[0];
                int j = curr_j + d[1];
                if (i < 0 || i >= N || j < 0 || j >= M)
                {
                    continue;
                }
                int 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 (Math.Abs(neighbor_val - curr_val) <= K)
                {
                    // Calculate the distance to the neighbor cell
                    int 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
                        pq.Enqueue(new int[] { neighbor_dist, i, j, neighbor_val });
                    }
                }
            }
        }
 
        // If the destination cell is not reachable from the source cell, return -1
        return -1;
    }
 
    static void Main(string[] args)
    {
        List<List<int>> mat = new List<List<int>>
        {
            new List<int> { -1, 0, 4, 3 },
            new List<int> { 6, 5, 7, 8 },
            new List<int> { 2, 1, 2, 0 }
        };
        int k = 4;
        List<int> src = new List<int> { 0, 0 };
        List<int> dest = new List<int> { 2, 3 };
        Console.WriteLine(ShortestPathLessThanK(mat, k, src, dest));
    }
}
 
// Priority Queue implementation for C#
class PriorityQueue<T>
{
    private List<T> data;
    private Comparison<T> comparison;
 
    public PriorityQueue(Comparison<T> comparison)
    {
        this.comparison = comparison;
        this.data = new List<T>();
    }
 
    public void Enqueue(T item)
    {
        data.Add(item);
        int childIndex = data.Count - 1;
        while (childIndex > 0)
        {
            int parentIndex = (childIndex - 1) / 2;
            if (comparison(data[childIndex], data[parentIndex]) >= 0)
                break;
 
            T tmp = data[childIndex];
            data[childIndex] = data[parentIndex];
            data[parentIndex] = tmp;
 
            childIndex = parentIndex;
        }
    }
 
    public T Dequeue()
    {
        int lastIndex = data.Count - 1;
        T frontItem = data[0];
        data[0] = data[lastIndex];
        data.RemoveAt(lastIndex);
 
        --lastIndex;
        int parentIndex = 0;
        while (true)
        {
            int leftChildIndex = parentIndex * 2 + 1;
            if (leftChildIndex > lastIndex)
                break;
 
            int rightChildIndex = leftChildIndex + 1;
            if (rightChildIndex <= lastIndex && comparison(data[rightChildIndex], data[leftChildIndex]) < 0)
                leftChildIndex = rightChildIndex;
 
            if (comparison(data[parentIndex], data[leftChildIndex]) <= 0)
                break;
 
            T tmp = data[parentIndex];
            data[parentIndex] = data[leftChildIndex];
            data[leftChildIndex] = tmp;
 
            parentIndex = leftChildIndex;
        }
 
        return frontItem;
    }
 
    public int Count
    {
        get { return data.Count; }
    }
}




function shortestPathLessThanK(mat, K, src, dest) {
  const N = mat.length;
  const M = mat[0].length;
  const dist = new Array(N).fill(null).map(() => new Array(M).fill(Infinity));
  dist[src[0]][src[1]] = 0;
  const pq = [];
  pq.push([0, src[0], src[1], mat[src[0]][src[1]]]);
 
  const dir = [[-1, 0], [1, 0], [0, 1], [0, -1]];
 
  while (pq.length > 0) {
    const [currDist, currI, currJ, currVal] = pq.shift();
    if (currI === dest[0] && currJ === dest[1]) {
      return currDist;
    }
    for (const d of dir) {
      const i = currI + d[0];
      const j = currJ + d[1];
      if (i < 0 || i >= N || j < 0 || j >= M) {
        continue;
      }
      const neighborVal = mat[i][j];
      if (Math.abs(neighborVal - currVal) <= K) {
        const neighborDist = currDist + 1;
        if (neighborDist < dist[i][j]) {
          dist[i][j] = neighborDist;
          pq.push([neighborDist, i, j, neighborVal]);
        }
      }
    }
  }
 
  return -1;
}
 
// Example usage
const mat = [[-1, 0, 4, 3], [6, 5, 7, 8], [2, 1, 2, 0]];
const k = 4;
const src = [0, 0];
const dest = [2, 3];
console.log(shortestPathLessThanK(mat, k, src, dest));

Output
7

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


Article Tags :