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); } |
7
Time Complexity: O(NlogN)
Auxiliary Space: O(1)
Please Login to comment...