Open In App

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

Last Updated : 09 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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




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


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


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




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

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

C++14




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


Java




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


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


C#




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


Javascript




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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads