📌  相关文章
📜  将所有大小为K的子数组转换为单个元素所需的最低成本

📅  最后修改于: 2021-05-17 03:44:05             🧑  作者: Mango

先决条件:滑动窗口中位数

给定一个由N个整数和一个整数K组成的数组arr [] ,任务是找到使长度为K的每个子数组的每个元素相等所需的最小成本。用另一个元素替换任何数组元素的成本是两者之间的绝对差。

例子:

方法:
若要找到将子数组的每个元素转换为单个元素的最低成本,请将子数组的每个元素更改为该子数组的中位数。请按照以下步骤解决问题:

  • 若要有效地找到每个正在运行的子数组的中位数,请使用多集获取每个子数组中元素的排序顺序。中位数将是此多集的中间元素
  • 对于下一个子数组,请从多集中删除前一个子数组的最左侧元素,然后将当前元素添加到多集中。
  • 将指针保持在中间,以有效地跟踪多组的中间元素。
  • 如果新加入的元素是比以前中量元素更小,移动中旬到其直接更小的元素。否则,请移至其下一个元素的中间。
  • 计算用等式替换子数组的每个元素的成本| A [i] –每个子数组的中位数|
  • 最后打印总费用。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
  
// Function to find the minimum
// cost to convert each element of
// every subarray of size K equal
int minimumCost(vector arr, int n,
                int k)
{
    // Stores the minimum cost
    int totalcost = 0;
    int i, j;
  
    // Stores the first K elements
    multiset 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 A({ 1, 2, 3, 4, 6 });
  
    cout << minimumCost(A, N, K);
}


输出:
7


时间复杂度: O(NlogN)
辅助空间: O(1)