Open In App

Minimize the absolute difference on path from first column to the last column

Last Updated : 29 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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




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




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


C#




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


Javascript




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


Python3




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


Output

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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads