Given a matrix arr[][] of size M * N, where arr[i][j] represents the height of the cell (row, col). The task is to find a path from top-left to bottom-right such that the value of the maximum difference in height between adjacent cells is minimum for that path.
Note: A path energy is the maximum absolute difference in heights between two consecutive cells of the path.
Examples:
Input:
Output: 1
Explanation: The path {1, 2, 1, 2, 2} has a maximum absolute difference of 1 in consecutive cells and this is better than all other possible pathsInput:
Output: 1
Explanation: The highlighted path is the path with minimum value of maximum adjacent difference.
An approach using DFS + Binary Search:
The idea is to use Binary search to solve this problem, if we assume a threshold value as mid, and check whether there exist a path through which we can reach to end, then that might be my answer, else look for some bigger values.
- Initialize a variable start = 0 and end = maximum possible energy required and a variable result
- Do the following while start ? end
- Calculate mid = (start + end) / 2
- Check if mid energy is valid energy required by choosing any path into the matrix
- Checking the valid energy using a valid function
- Check if we go outside the matrix or if cell(i, j) is visited or absolute difference between consecutive cells is greater than our assumed maximum energy required
- If true, then return false
- Check if we reach the bottom-right cell
- If true, then return true
- Make the current cell(i, j) visited
- Make all four direction calls and check if any path is valid
- If true, then return true.
- Otherwise, return false
- Check if we go outside the matrix or if cell(i, j) is visited or absolute difference between consecutive cells is greater than our assumed maximum energy required
- Checking the valid energy using a valid function
- If the value from a valid function returns true, then update the result and move the end to mid – 1
- Otherwise, move the start to mid + 1
- Return the result
Below is the implementation of the above approach.
// C++ code to implement the above approach #include <bits/stdc++.h> using namespace std;
int m, n;
// Function to check if there is a valid path bool isValid( int i, int j, int x,
vector<vector< bool > >& visited,
vector<vector< int > >& arr, long long parent)
{ // Check if we go outside the matrix or
// cell(i, j) is visited or absolute
// difference between consecutive cell
// is greater than our assumed maximum
// energy required If true,
// then return false
if (i < 0 || j < 0 || i >= m || j >= n || visited[i][j]
|| abs (( long long )arr[i][j] - parent) > x)
return false ;
// Check if we reach at bottom-right
// cell If true, then return true
if (i == m - 1 && j == n - 1)
return true ;
// Make the current cell(i, j) visited
visited[i][j] = true ;
// Make all four direction call and
// check if any path is valid If true,
// then return true.
if (isValid(i + 1, j, x, visited, arr, arr[i][j]))
return true ;
if (isValid(i - 1, j, x, visited, arr, arr[i][j]))
return true ;
if (isValid(i, j + 1, x, visited, arr, arr[i][j]))
return true ;
if (isValid(i, j - 1, x, visited, arr, arr[i][j]))
return true ;
// Otherwise, return false
return false ;
} // Function to find the minimum value among // the maximum adjacent differences int minimumEnergyPath(vector<vector< int > >& arr)
{ // Initialize a variable start = 0
// and end = maximum possible
// energy required
int start = 0, end = 10000000;
// Initialize a variable result
int result = arr[0][0];
// Loop to implement the binary search
while (start <= end) {
int mid = (start + end) / 2;
// Initialize a visited array
// of size (m * n)
vector<vector< bool > > visited(
m, vector< bool >(n, false ));
// Check if mid energy is valid
// energy required by choosing any
// path into the matrix If true,
// update the result and
// move end to mid - 1
if (isValid(0, 0, mid, visited, arr, arr[0][0])) {
result = mid;
end = mid - 1;
}
// Otherwise, move start to mid + 1
else {
start = mid + 1;
}
}
// Return the result
return result;
} // Driver code int main()
{ vector<vector< int > > arr = {
{ 1, 2, 1 },
{ 2, 8, 2 },
{ 2, 4, 2 },
};
m = arr.size(), n = arr[0].size();
// Function Call
cout << minimumEnergyPath(arr);
return 0;
} |
// Java code to implement the above approach import java.io.*;
class GFG {
static int m, n;
// Function to check if there is a valid path
static boolean isValid( int i, int j, int x,
boolean [][] visited, int [][] arr,
long parent)
{
// Check if we go outside the matrix or
// cell(i, j) is visited or absolute
// difference between consecutive cell
// is greater than our assumed maximum
// energy required If true,
// then return false
if (i < 0 || j < 0 || i >= m || j >= n
|| visited[i][j]
|| Math.abs(arr[i][j] - parent) > x) {
return false ;
}
// Check if we reach at bottom-right
// cell If true, then return true
if (i == m - 1 && j == n - 1 ) {
return true ;
}
// Make the current cell(i, j) visited
visited[i][j] = true ;
// Make all four direction call and
// check if any path is valid If true,
// then return true.
if (isValid(i + 1 , j, x, visited, arr, arr[i][j]))
return true ;
if (isValid(i - 1 , j, x, visited, arr, arr[i][j]))
return true ;
if (isValid(i, j + 1 , x, visited, arr, arr[i][j]))
return true ;
if (isValid(i, j - 1 , x, visited, arr, arr[i][j]))
return true ;
// Otherwise, return false
return false ;
}
// Function to find the minimum value among
// the maximum adjacent differences
static int minimumEnergyPath( int [][] arr)
{
// Initialize a variable start = 0
// and end = maximum possible
// energy required
int start = 0 , end = 10000000 ;
// Initialize a variable result
int result = arr[ 0 ][ 0 ];
// Loop to implement the binary search
while (start <= end) {
int mid = (start + end) / 2 ;
// Initialize a visited array
// of size (m * n)
boolean [][] visited = new boolean [m][n];
// Check if mid energy is valid
// energy required by choosing any
// path into the matrix If true,
// update the result and
// move end to mid - 1
if (isValid( 0 , 0 , mid, visited, arr,
arr[ 0 ][ 0 ])) {
result = mid;
end = mid - 1 ;
}
// Otherwise, move start to mid + 1
else {
start = mid + 1 ;
}
}
// Return the result
return result;
}
public static void main(String[] args)
{
int [][] arr
= { { 1 , 2 , 1 }, { 2 , 8 , 2 }, { 2 , 4 , 2 } };
m = arr.length;
n = arr[ 0 ].length;
// Function call
System.out.print(minimumEnergyPath(arr));
}
} // This code is contributed by lokesh. |
# Python code to implement the above approach m,n = 0 , 0
# Function to check if there is a valid path def isValid(i,j,x,visited,arr,parent):
# Check if we go outside the matrix or
# cell(i, j) is visited or absolute
# difference between consecutive cell
# is greater than our assumed maximum
# energy required If true,
# then return false
if (i< 0 or j< 0 or i> = m or j> = n or visited[i][j] or abs (arr[i][j] - parent)>x):
return False
# Check if we reach at bottom-right
# cell If true, then return true
if (i = = m - 1 and j = = n - 1 ):
return True
# Make the current cell(i, j) visited
visited[i][j] = True
# Make all four direction call and
# check if any path is valid If true,
# then return true.
if (isValid(i + 1 ,j,x,visited,arr,arr[i][j])):
return True
if (isValid(i - 1 ,j,x,visited,arr,arr[i][j])):
return True
if (isValid(i,j + 1 ,x,visited,arr,arr[i][j])):
return True
if (isValid(i,j - 1 ,x,visited,arr,arr[i][j])):
return True
# Otherwise, return false
return False
# Function to find the minimum value among # the maximum adjacent differences def minimumEnergyPath(arr):
# Initialize a variable start = 0
# and end = maximum possible
# energy required
start,end = 0 , 10000000
# Initialize a variable result
result = arr[ 0 ][ 0 ]
# Loop to implement the binary search
while (start< = end):
mid = (start + end) / / 2
# Initialize a visited array
# of size (m * n)
visited = [[ False for i in range (n)] for j in range (m)]
# Check if mid energy is valid
# energy required by choosing any
# path into the matrix If true,
# update the result and
# move end to mid - 1
if (isValid( 0 , 0 ,mid,visited,arr,arr[ 0 ][ 0 ])):
result = mid
end = mid - 1
# Otherwise, move start to mid + 1
else :
start = mid + 1
# Return the result
return result
# Driver Code arr = [[ 1 , 2 , 1 ],[ 2 , 8 , 2 ],[ 2 , 4 , 2 ]]
m = len (arr)
n = len (arr[ 0 ])
# Function Call print (minimumEnergyPath(arr))
# This code is contributed by Pushpesh Raj. |
// C# implementation using System;
public class GFG {
static int m, n;
// Function to check if there is a valid path
public static bool isValid( int i, int j, int x,
bool [, ] visited,
int [, ] arr, int parent)
{
// Check if we go outside the matrix or
// cell(i, j) is visited or absolute
// difference between consecutive cell
// is greater than our assumed maximum
// energy required If true,
// then return false
if ((i < 0) || (j < 0) || (i >= m) || (j >= n)
|| (visited[i, j] == true )
|| (Math.Abs(arr[i, j] - parent) > x))
return false ;
// Check if we reach at bottom-right
// cell If true, then return true
if (i == m - 1 && j == n - 1)
return true ;
// Make the current cell(i, j) visited
visited[i, j] = true ;
// Make all four direction call and
// check if any path is valid If true,
// then return true.
if (isValid(i + 1, j, x, visited, arr, arr[i, j]))
return true ;
if (isValid(i - 1, j, x, visited, arr, arr[i, j]))
return true ;
if (isValid(i, j + 1, x, visited, arr, arr[i, j]))
return true ;
if (isValid(i, j - 1, x, visited, arr, arr[i, j]))
return true ;
// Otherwise, return false
return false ;
}
// Function to find the minimum value among
// the maximum adjacent differences
public static int minimumEnergyPath( int [, ] arr)
{
// Initialize a variable start = 0
// and end = maximum possible
// energy required
int start = 0, end = 10000000;
// Initialize a variable result
int result = arr[0, 0];
// Loop to implement the binary search
while (start <= end) {
int mid = ( int )((start + end) / 2);
// Initialize a visited array
// of size (m * n)
bool [, ] visited = new bool [m, n];
for ( int i = 0; i < m; i++) {
for ( int j = 0; j < n; j++) {
visited[i, j] = false ;
}
}
// Check if mid energy is valid
// energy required by choosing any
// path into the matrix If true,
// update the result and
// move end to mid - 1
if (isValid(0, 0, mid, visited, arr, arr[0, 0])
== true ) {
result = mid;
end = mid - 1;
}
// Otherwise, move start to mid + 1
else {
start = mid + 1;
}
}
// Return the result
return result;
}
static public void Main()
{
int [, ] arr = {
{ 1, 2, 1 },
{ 2, 8, 2 },
{ 2, 4, 2 },
};
m = arr.GetLength(0);
n = arr.GetLength(1);
// Function Call
Console.WriteLine(minimumEnergyPath(arr));
}
} // This code is contributed by ksam24000 |
// JavaScript code for the above approach let m, n; // Function to check if there is a valid path function isValid(i, j, x, visited, arr, parent)
{ // Check if we go outside the matrix or
// cell(i, j) is visited or absolute
// difference between consecutive cell
// is greater than our assumed maximum
// energy required If true,
// then return false
if (i < 0 || j < 0 || i >= m || j >= n || visited[i][j]
|| Math.abs(arr[i][j] - parent) > x)
return false ;
// Check if we reach at bottom-right
// cell If true, then return true
if (i == m - 1 && j == n - 1)
return true ;
// make the current cell(i, j) visited
visited[i][j] = true ;
// make all four direction call and
// check if any path is valid If true,
// then return true.
if (isValid(i + 1, j, x, visited, arr, arr[i][j]))
return true ;
if (isValid(i - 1, j, x, visited, arr, arr[i][j]))
return true ;
if (isValid(i, j + 1, x, visited, arr, arr[i][j]))
return true ;
if (isValid(i, j - 1, x, visited, arr, arr[i][j]))
return true ;
// Otherwise, return false
return false ;
} // Function to find the minimum value among // the maximum adjacent differences function minimumEnergyPath(arr)
{ // Initialize a variable start = 0
// and end = maximum possible
// energy required
let start = 0, end = 10000000;
// Initialize a variable result
let result = arr[0][0];
// Loop to implement the binary search
while (start <= end) {
let mid = Math.floor((start + end) / 2);
// Initialize a visited array
// of size (m * n)
let visited
= new Array(m)
for (let i = 0; i < m; i++)
{
visited[i] = new Array(n).fill(0)
}
// Check if mid energy is valid
// energy required by choosing any
// path into the matrix If true,
// update the result and
// move end to mid - 1
if (isValid(0, 0, mid, visited, arr, arr[0][0])) {
result = mid;
end = mid - 1;
}
// Otherwise, move start to mid + 1
else {
start = mid + 1;
}
}
// Return the result
return result;
} // Driver code let arr = [ [ 1, 2, 1 ],
[ 2, 8, 2 ],
[ 2, 4, 2 ],
]; m = arr.length, n = arr[0].length; // Function Call console.log(minimumEnergyPath(arr)); // This code is contributed by Potta Lokesh |
1
Time Complexity: O(log2(K) * (M*N)), where K is the maximum element in the matrix and M, and N are the number of rows and columns in the given matrix respectively.
Auxiliary Space: O(M * N)