Minimum cost required to convert all Subarrays of size K to a single element

Prerequisite: Sliding Window Median
Given an array arr[] consisting of N integers and an integer K, the task is to find the minimum cost required to make each element of every subarray of length K equal. Cost of replacing any array element by another element is the absolute difference between the two.
Examples:Â
Â
Input: A[] = {1, 2, 3, 4, 6}, K = 3Â
Output: 7Â
Explanation:Â
Subarray 1: Cost to convert subarray {1, 2, 3} to {2, 2, 2} = |1-2| + |2-2| + |3-2| = 2Â
Subarray 2: Cost to convert subarray {2, 3, 4} to {3, 3, 3} = |2-3| + |3-3| + |4-3| = 2Â
Subarray 3: Cost to convert subarray {3, 4, 6} to {4, 4, 4} = |3-4| + |4-4| + |6-4| = 3Â
Minimum Cost = 2 + 2 + 3 = 7/
Input: A[] = {2, 3, 4, 4, 1, 7, 6}, K = 4Â
Output: 21Â
Â
Â
Approach:Â
To find the minimum cost to convert each element of the subarray to a single element, change every element of the subarray to the median of that subarray. Follow the steps below to solve the problem:Â
Â
- To find the median for each running subarray efficiently, use a multiset to get the sorted order of elements in each subarray. Median will be the middle element of this multiset.
- For the next subarray remove the leftmost element of the previous subarray from the multiset, add the current element to the multiset.
- Keep a pointer mid to efficiently keep track of the middle element of the multiset.
- If the newly added element is smaller than the previous middle element, move mid to its immediate smaller element. Otherwise, move mid to its immediate next element.
- Calculate cost of replacing every element of the subarray by the equation | A[i] – medianeach_subarray |.
- Finally print the total cost.
Below is the implementation for the above approach:
Â
C++
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std;   // Function to find the minimum // cost to convert each element of // every subarray of size K equal int minimumCost(vector<int> arr, int n,                 int k) {     // Stores the minimum cost     int totalcost = 0;     int i, j;       // Stores the first K elements     multiset<int> mp(arr.begin(),                      arr.begin() + k);       if (k == n) {           // Obtain the middle element of         // the multiset         auto mid = next(mp.begin(),                         n / 2 - ((k + 1) % 2));           int z = *mid;           // Calculate cost for the subarray         for (i = 0; i < n; i++)             totalcost += abs(z - arr[i]);           // Return the total cost         return totalcost;     }     else {           // Obtain the middle element         // in multiset         auto mid = next(mp.begin(),                         k / 2 - ((k + 1) % 2));           for (i = k; i < n; i++) {               int zz = *mid;             int cost = 0;             for (j = i - k; j < i; j++) {                   // Cost for the previous                 // k length subarray                 cost += abs(arr[j] - zz);             }             totalcost += cost;               // Insert current element             // into multiset             mp.insert(arr[i]);               if (arr[i] < *mid) {                   // New element appears                 // to the left of mid                 mid--;             }               if (arr[i - k] <= *mid) {                   // New element appears                 // to the right of mid                 mid++;             }               // Remove leftmost element             // from the window             mp.erase(mp.lower_bound(arr[i - k]));               // For last element             if (i == n - 1) {                 zz = *mid;                 cost = 0;                   for (j = i - k + 1;                      j <= i; j++) {                       // Calculate cost for the subarray                     cost += abs(zz - arr[j]);                 }                   totalcost += cost;             }         }           // Return the total cost         return totalcost;     } }   // Driver Code int main() {     int N = 5, K = 3;       vector<int> A({ 1, 2, 3, 4, 6 });       cout << minimumCost(A, N, K); } |
Java
import java.util.*;   class GFG {     // Function to find the minimum   // cost to convert each element of   // every subarray of size K equal   static int minimumCost(int[] arr, int n, int k)   {     // Stores the minimum cost     int totalcost = 0;     int i = 0, j = 0;       // Stores the first K elements     List<Integer> mp = new ArrayList<Integer>();     for (int x = 0; x < k; x++) {       mp.add(arr[x]);     }     Collections.sort(mp);       if (k == n) {       // Obtain the middle element of       // the list       int mid = mp.get(n / 2 - ((k + 1) % 2));       int z = mid;         // Calculate cost for the subarray       for (i = 0; i < n; i++) {         totalcost += Math.abs(z - arr[i]);       }         // Return the total cost       return totalcost;     }     else {       // Obtain the middle element in the list       int mid = mp.get(k / 2 - ((k + 1) % 2));         for (i = k; i < n; i++) {         int zz = mid;         int cost = 0;         for (j = i - k; j < i; j++) {           // Cost for the previous           // k length subarray           cost += Math.abs(arr[j] - zz);         }         totalcost += cost;           // Insert current element         // into the list         int idx           = Collections.binarySearch(mp, arr[i]);         if (idx < 0) {           mp.add(-idx - 1, arr[i]);         }         else {           mp.add(idx, arr[i]);         }           if (arr[i] < mid) {           // New element appears           // to the left of mid           mid = mp.get(k / 2 - ((k + 1) % 2));         }           if (arr[i - k] <= mid) {           // New element appears           // to the right of mid           mid = mp.get(k / 2 - ((k + 1) % 2) + 1);         }           // Remove leftmost element         // from the window         idx = Collections.binarySearch(mp,                                        arr[i - k]);         if (idx >= 0) {           mp.remove(idx);         }           // For last element         if (i == n - 1) {           zz = mid;           cost = 0;           for (j = i - k + 1; j < i + 1; j++) {             // Calculate cost for the subarray             cost += Math.abs(zz - arr[j]);           }           totalcost += cost;         }       }         // Return the total cost       return totalcost;     }   }     // Driver Code   public static void main(String[] args)   {     int N = 5, K = 3;     int[] A = { 1, 2, 3, 4, 6 };     System.out.println(minimumCost(A, N, K));   } }   // This code is contributed by phasing17. |
Python3
import bisect   # Function to find the minimum # cost to convert each element of # every subarray of size K equal def minimumCost(arr, n, k):     # Stores the minimum cost     totalcost = 0    i, j = 0, 0      # Stores the first K elements     mp = sorted(arr[:k])       if k == n:         # Obtain the middle element of         # the list         mid = mp[n // 2 - ((k + 1) % 2)]         z = mid           # Calculate cost for the subarray         for i in range(n):             totalcost += abs(z - arr[i])           # Return the total cost         return totalcost     else:         # Obtain the middle element in the list         mid = mp[k // 2 - ((k + 1) % 2)]           for i in range(k, n):             zz = mid             cost = 0            for j in range(i - k, i):                 # Cost for the previous                 # k length subarray                 cost += abs(arr[j] - zz)             totalcost += cost               # Insert current element             # into the list             bisect.insort(mp, arr[i])               if arr[i] < mid:                 # New element appears                 # to the left of mid                 mid = mp[k // 2 - ((k + 1) % 2)]               if arr[i - k] <= mid:                 # New element appears                 # to the right of mid                 mid = mp[k // 2 - ((k + 1) % 2) + 1]               # Remove leftmost element             # from the window             idx = bisect.bisect_left(mp, arr[i - k])             mp.pop(idx)               # For last element             if i == n - 1:                 zz = mid                 cost = 0                for j in range(i - k + 1, i + 1):                     # Calculate cost for the subarray                     cost += abs(zz - arr[j])                 totalcost += cost           # Return the total cost         return totalcost   # Driver Code if __name__ == '__main__':     N, K = 5, 3    A = [1, 2, 3, 4, 6]     print(minimumCost(A, N, K))       # This code is contributed by phasing17. |
Javascript
// Javascript program for the above approach   // Function to find the minimum cost to convert each // element of every subarray of size K equal function minimumCost(arr, n, k) {   // Stores the minimum cost   let totalcost = 0;   let i = 0,     j = 0;     // Stores the first K elements   let mp = arr.slice(0, k).sort((a, b) => a - b);     if (k == n) {     // Obtain the middle element of the list     let mid = mp[(Math.floor(n / 2) - ((k + 1) % 2))];     let z = mid;       // Calculate cost for the subarray     for (let i = 0; i < n; i++) {       totalcost += Math.abs(z - arr[i]);     }       // Return the total cost     return totalcost;   } else {     // Obtain the middle element in the list     let mid = mp[(Math.floor(k / 2) - ((k + 1) % 2))];       for (let i = k; i < n; i++) {       let zz = mid;       let cost = 0;       for (let j = i - k; j < i; j++) {         // Cost for the previous k length subarray         cost += Math.abs(arr[j] - zz);       }       totalcost += cost;         // Insert current element into the list       mp.splice(bisect_left(mp, arr[i]), 0, arr[i]);         if (arr[i] < mid) {         // New element appears to the left of mid         mid = mp[(Math.floor(k / 2) - ((k + 1) % 2))];       }         if (arr[i - k] <= mid) {         // New element appears to the right of mid         mid = mp[(Math.floor(k / 2) - ((k + 1) % 2) + 1)];       }         // Remove leftmost element from the window       mp.splice(bisect_left(mp, arr[i - k]), 1);         // For last element       if (i == n - 1) {         zz = mid;         cost = 0;         for (let j = i - k + 1; j <= i; j++) {           // Calculate cost for the subarray           cost += Math.abs(zz - arr[j]);         }         totalcost += cost;       }     }       // Return the total cost     return totalcost;   } }   // Driver Code let N = 5,   K = 3; let A = [1, 2, 3, 4, 6]; console.log(minimumCost(A, N, K));   // Returns the index at which the element should be inserted into the sorted list function bisect_left(arr, x) {   let lo = 0,     hi = arr.length;   while (lo < hi) {     let mid = Math.floor((lo + hi) / 2);     if (arr[mid] < x) lo = mid + 1;     else hi = mid;   }   return lo; }   // contributed by adityasharmadev01 |
C#
// C# Equivalent using System; using System.Collections.Generic;    public class GFG {     // Function to find the minimum     // cost to convert each element of     // every subarray of size K equal     static int minimumCost(int[] arr, int n, int k)     {         // Stores the minimum cost         int totalcost = 0;         int i = 0, j = 0;            // Stores the first K elements         List<int> mp = new List<int>();         for (int x = 0; x < k; x++)         {             mp.Add(arr[x]);         }         mp.Sort();            if (k == n)         {             // Obtain the middle element of             // the list             int mid = mp[n / 2 - (k + 1) % 2];             int z = mid;                // Calculate cost for the subarray             for (i = 0; i < n; i++)             {                 totalcost += Math.Abs(z - arr[i]);             }                // Return the total cost             return totalcost;         }         else        {             // Obtain the middle element in the list             int mid = mp[k / 2 - (k + 1) % 2];                for (i = k; i < n; i++)             {                 int zz = mid;                 int cost = 0;                 for (j = i - k; j < i; j++)                 {                     // Cost for the previous                     // k length subarray                     cost += Math.Abs(arr[j] - zz);                 }                 totalcost += cost;                    // Insert current element                 // into the list                 int idx = mp.BinarySearch(arr[i]);                 if (idx < 0)                 {                     mp.Insert(-idx - 1, arr[i]);                 }                 else                {                     mp.Insert(idx, arr[i]);                 }                    if (arr[i] < mid)                 {                     // New element appears                     // to the left of mid                     mid = mp[k / 2 - (k + 1) % 2];                 }                    if (arr[i - k] <= mid)                 {                     // New element appears                     // to the right of mid                     mid = mp[k / 2 - (k + 1) % 2 + 1];                 }                    // Remove leftmost element                 // from the window                 idx = mp.BinarySearch(arr[i - k]);                 if (idx >= 0)                 {                     mp.RemoveAt(idx);                 }                    // For last element                 if (i == n - 1)                 {                     zz = mid;                     cost = 0;                     for (j = i - k + 1; j < i + 1; j++)                     {                         // Calculate cost for the subarray                         cost += Math.Abs(zz - arr[j]);                     }                     totalcost += cost;                 }             }                // Return the total cost             return totalcost;         }     }        // Driver Code     public static void Main(String[] args)     {         int N = 5, K = 3;         int[] A = { 1, 2, 3, 4, 6 };         Console.Write(minimumCost(A, N, K));     } } |
7
Â
Time Complexity: O(NlogN)Â
Auxiliary Space: O(1)
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



