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++
#include <bits/stdc++.h>
using namespace std;
int minCostPath( int n, int m, vector<vector< int > >& arr)
{
vector<pair< int , int > > res;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
res.push_back({ arr[i][j], j });
}
}
sort(begin(res), end(res));
unordered_map< int , int > hsh;
deque< int > dq;
int i = 0, ans = 1e9;
for ( int j = 0; j < res.size(); j++) {
hsh[res[j].second]++;
while (hsh.size() == m) {
hsh[res[i].second]--;
if (hsh[res[i].second] == 0) {
hsh.erase(res[i].second);
}
ans = min(ans, res[j].first - res[i].first);
i++;
}
}
return ans;
}
int main()
{
int N = 3;
int M = 3;
vector<vector< int > > arr = {{1, 2, 3}, {1, 2, 3}, {2, 1, 1}};
cout << minCostPath(N, M, arr);
return 0;
}
|
Java
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<>();
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < m; j++) {
res.add( new Pair<>(arr[i][j], j));
}
}
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;
for ( int j = 0 ; j < res.size(); j++) {
hsh.put(
res.get(j).getValue(),
hsh.getOrDefault(res.get(j).getValue(), 0 )
+ 1 );
while (hsh.size() == m) {
hsh.put(res.get(i).getValue(),
hsh.get(res.get(i).getValue()) - 1 );
if (hsh.get(res.get(i).getValue()) == 0 ) {
hsh.remove(res.get(i).getValue());
}
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 } };
System.out.println(minCostPath(N, M, arr));
}
}
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class MainClass
{
public static int MinCostPath( int n, int m, List<List< int >> arr)
{
List<Tuple< int , int >> res = new List<Tuple< int , int >>();
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < m; j++)
{
res.Add( new Tuple< int , int >(arr[i][j], j));
}
}
res = res.OrderBy(t => t.Item1).ToList();
Dictionary< int , int > hsh = new Dictionary< int , int >();
int index = 0, ans = int .MaxValue;
for ( int j = 0; j < res.Count; j++)
{
if (hsh.ContainsKey(res[j].Item2))
{
hsh[res[j].Item2]++;
}
else
{
hsh.Add(res[j].Item2, 1);
}
while (hsh.Count == m)
{
hsh[res[index].Item2]--;
if (hsh[res[index].Item2] == 0)
{
hsh.Remove(res[index].Item2);
}
ans = Math.Min(ans, res[j].Item1 - res[index].Item1);
index++;
}
}
return ans;
}
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}
};
Console.WriteLine(MinCostPath(N, M, arr));
}
}
|
Javascript
function minCostPath(n, m, arr) {
let res = [];
for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
res.push([arr[i][j], j]);
}
}
res.sort((a, b) => a[0] - b[0]);
let hsh = {};
let dq = [];
let i = 0;
let ans = Infinity;
for (let j = 0; j < res.length; j++) {
hsh[res[j][1]] = (hsh[res[j][1]] || 0) + 1;
while (Object.keys(hsh).length === m) {
hsh[res[i][1]]--;
if (hsh[res[i][1]] === 0) {
delete hsh[res[i][1]];
}
ans = Math.min(ans, res[j][0] - res[i][0]);
i++;
}
}
return ans;
}
let N = 3;
let M = 3;
let arr = [[1, 2, 3], [1, 2, 3], [2, 1, 1]];
console.log(minCostPath(N, M, arr));
|
Python3
from collections import deque
def minCostPath(n, m, arr):
res = []
for i in range (n):
for j in range (m):
res.append((arr[i][j], j))
res.sort()
hsh = {}
dq = deque()
i = 0
ans = float ( 'inf' )
for j in range ( len (res)):
hsh[res[j][ 1 ]] = hsh.get(res[j][ 1 ], 0 ) + 1
while len (hsh) = = m:
hsh[res[i][ 1 ]] - = 1
if hsh[res[i][ 1 ]] = = 0 :
del hsh[res[i][ 1 ]]
ans = min (ans, res[j][ 0 ] - res[i][ 0 ])
i + = 1
return ans
if __name__ = = "__main__" :
N = 3
M = 3
arr = [[ 1 , 2 , 3 ], [ 1 , 2 , 3 ], [ 2 , 1 , 1 ]]
print (minCostPath(N, M, arr))
|
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)
|