Given an integer matrix mat[][] with N rows and M columns. The task is to minimize the absolute difference between the maximum and minimum elements visited along the path from the first column to the last column. We can jump from the current column to any row in the next column.
Note: We can start from first column (any row) and end at last column (any row).
Examples:
Input: N = 3, M = 3, mat[][] = {{1, 2, 3}, {1, 2, 3}, {2, 1, 1}}
Output: 0
Explanation: We travel along the path A[0][0], A[2][1], A[2][2]. Cost of the path is 1 – 1 = 0.Input: N = 1, M = 4, mat[][] = {{1, 2, 3, 4}}
Output: 3
Explanation: There is only one path A[0][0], A[0][1], A[0][2], A[0][3]. Cost of the path is 4 – 1 = 3.
Approach: To solve the problem, follow the below idea:
The approach is to first store the elements in vector along with column index. After sorting the vector, iterate here and if all indexes are being stored in map it means we have iterated through all the columns. Get the minimum and maximum element and get the difference and update the minimum value.
Step-by-step algorithm:
-
Sorting:
- The function starts by creating list res containing tuples of values from the matrix along with their corresponding column indices. This list is then sorted based on the values.
-
Sliding Window Technique:
- A deque (dq) is used to implement a sliding window over the sorted list of tuples.
- A defaultdict (hsh) is used to keep track of the columns included in the current window.
- Two pointers, i and j, are used to define the current window. Initially, i is set to 0, and j iterates through the sorted list.
-
Minimize Window:
- The window expands to the right (j) by incrementing the frequency of the current column in the hsh dictionary.
- The window contracts from the left (i) when the length of hsh reaches M. The frequency of the leftmost column is decreased, and if it becomes zero, the column is removed from hsh.
-
Update Minimum Cost:
- While maintaining the window, the difference between the maximum and minimum values within the window is computed (res[j][0] – res[i][0]).
- The minimum cost is updated whenever a smaller difference is found.
-
Final Result:
- The final result is the minimum cost obtained during the entire process.
Below is the Implementation of the algorithm:
// C++ Implementation #include <bits/stdc++.h> using namespace std;
// Function to find Minimum cost path int minCostPath( int n, int m, vector<vector< int > >& arr)
{ // Create a pair vector
vector<pair< int , int > > res;
// Iterate in arr store it in vector
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
res.push_back({ arr[i][j], j });
}
}
// Sort the pair vector in ascending order
sort(begin(res), end(res));
// Intialize a map
unordered_map< int , int > hsh;
deque< int > dq;
int i = 0, ans = 1e9;
// Iterate in vector res
for ( int j = 0; j < res.size(); j++) {
// Increase the value in map
hsh[res[j].second]++;
// If the size becomes upto column
while (hsh.size() == m) {
// Reduce the value in map
hsh[res[i].second]--;
// Erase value from map
if (hsh[res[i].second] == 0) {
hsh.erase(res[i].second);
}
// Get the difference and update the
// minimum
ans = min(ans, res[j].first - res[i].first);
i++;
}
}
return ans;
} // Driver code int main()
{ int N = 3;
int M = 3;
vector<vector< int > > arr = {{1, 2, 3}, {1, 2, 3}, {2, 1, 1}};
// Function call
cout << minCostPath(N, M, arr);
return 0;
} |
// Java Implementation import java.util.*;
public class MinCostPath {
public static class Pair<K, V> {
private final K key;
private final V value;
public Pair(K key, V value)
{
this .key = key;
this .value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
public static int minCostPath( int n, int m, int [][] arr)
{
List<Pair<Integer, Integer> > res
= new ArrayList<>();
// Iterate through the array and store the elements
// in the list
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < m; j++) {
res.add( new Pair<>(arr[i][j], j));
}
}
// Sort the list in ascending order
Collections.sort(
res, new Comparator<Pair<Integer, Integer> >() {
@Override
public int compare(
Pair<Integer, Integer> p1,
Pair<Integer, Integer> p2)
{
return p1.getKey().compareTo(
p2.getKey());
}
});
Map<Integer, Integer> hsh = new HashMap<>();
Deque<Integer> dq = new ArrayDeque<>();
int i = 0 , ans = Integer.MAX_VALUE;
// Iterate through the list
for ( int j = 0 ; j < res.size(); j++) {
// Increase the value in the map
hsh.put(
res.get(j).getValue(),
hsh.getOrDefault(res.get(j).getValue(), 0 )
+ 1 );
// If the size becomes equal to the number of
// columns
while (hsh.size() == m) {
// Reduce the value in the map
hsh.put(res.get(i).getValue(),
hsh.get(res.get(i).getValue()) - 1 );
// Remove the value from the map if it
// becomes 0
if (hsh.get(res.get(i).getValue()) == 0 ) {
hsh.remove(res.get(i).getValue());
}
// Calculate the difference and update the
// minimum
ans = Math.min(ans,
res.get(j).getKey()
- res.get(i).getKey());
i++;
}
}
return ans;
}
public static void main(String[] args)
{
int N = 3 ;
int M = 3 ;
int [][] arr
= { { 1 , 2 , 3 }, { 1 , 2 , 3 }, { 2 , 1 , 1 } };
// Function call
System.out.println(minCostPath(N, M, arr));
}
} // This code is contributed by Tapesh(tapeshdu420) |
using System;
using System.Collections.Generic;
using System.Linq;
public class MainClass
{ // Function to find Minimum cost path
public static int MinCostPath( int n, int m, List<List< int >> arr)
{
// Create a list of tuples
List<Tuple< int , int >> res = new List<Tuple< int , int >>();
// Iterate through arr and store it in the list
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < m; j++)
{
res.Add( new Tuple< int , int >(arr[i][j], j));
}
}
// Sort the list of tuples in ascending order
res = res.OrderBy(t => t.Item1).ToList();
// Intialize a dictionary
Dictionary< int , int > hsh = new Dictionary< int , int >();
int index = 0, ans = int .MaxValue;
// Iterate through the list res
for ( int j = 0; j < res.Count; j++)
{
// Increase the value in dictionary
if (hsh.ContainsKey(res[j].Item2))
{
hsh[res[j].Item2]++;
}
else
{
hsh.Add(res[j].Item2, 1);
}
// If the size becomes upto column
while (hsh.Count == m)
{
// Reduce the value in dictionary
hsh[res[index].Item2]--;
// Remove value from dictionary if it becomes zero
if (hsh[res[index].Item2] == 0)
{
hsh.Remove(res[index].Item2);
}
// Get the difference and update the minimum
ans = Math.Min(ans, res[j].Item1 - res[index].Item1);
index++;
}
}
return ans;
}
// Driver code
public static void Main( string [] args)
{
int N = 3;
int M = 3;
List<List< int >> arr = new List<List< int >>()
{
new List< int >() {1, 2, 3},
new List< int >() {1, 2, 3},
new List< int >() {2, 1, 1}
};
// Function call
Console.WriteLine(MinCostPath(N, M, arr));
}
} |
// Function to find Minimum cost path function minCostPath(n, m, arr) {
// Create an array of pairs
let res = [];
// Iterate in arr and store it in the array
for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
res.push([arr[i][j], j]);
}
}
// Sort the array of pairs in ascending order
res.sort((a, b) => a[0] - b[0]);
// Initialize a map as object
let hsh = {};
let dq = [];
let i = 0;
let ans = Infinity;
// Iterate in the array res
for (let j = 0; j < res.length; j++) {
// Increase the value in the dictionary
hsh[res[j][1]] = (hsh[res[j][1]] || 0) + 1;
// If the size becomes up to column
while (Object.keys(hsh).length === m) {
// Reduce the value in the dictionary
hsh[res[i][1]]--;
// Erase value from dictionary
if (hsh[res[i][1]] === 0) {
delete hsh[res[i][1]];
}
// Get the difference and update the minimum
ans = Math.min(ans, res[j][0] - res[i][0]);
i++;
}
}
return ans;
} // Driver code let N = 3; let M = 3; let arr = [[1, 2, 3], [1, 2, 3], [2, 1, 1]]; // Function call console.log(minCostPath(N, M, arr)); |
from collections import deque
# Function to find Minimum cost path def minCostPath(n, m, arr):
# Create a list of pairs
res = []
# Iterate in arr and store it in the list
for i in range (n):
for j in range (m):
res.append((arr[i][j], j))
# Sort the list of pairs in ascending order
res.sort()
# Initialize a dictionary
hsh = {}
dq = deque()
i = 0
ans = float ( 'inf' )
# Iterate in the list res
for j in range ( len (res)):
# Increase the value in the dictionary
hsh[res[j][ 1 ]] = hsh.get(res[j][ 1 ], 0 ) + 1
# If the size becomes up to column
while len (hsh) = = m:
# Reduce the value in the dictionary
hsh[res[i][ 1 ]] - = 1
# Erase value from dictionary
if hsh[res[i][ 1 ]] = = 0 :
del hsh[res[i][ 1 ]]
# Get the difference and update the minimum
ans = min (ans, res[j][ 0 ] - res[i][ 0 ])
i + = 1
return ans
# Driver code if __name__ = = "__main__" :
N = 3
M = 3
arr = [[ 1 , 2 , 3 ], [ 1 , 2 , 3 ], [ 2 , 1 , 1 ]]
# Function call
print (minCostPath(N, M, arr))
|
0
Time Complexity: O(N * M * log(N * M)), where N is the number of rows and M is the number of columns.
Auxiliary Space: O(M)