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

📅  最后修改于: 2021-10-26 05:16:05             🧑  作者: Mango

先决条件:滑动窗口中位数
给定一个由N 个整数和一个整数K组成的数组 arr[] ,任务是找到使每个长度为K 的子数组的每个元素相等所需的最小成本。用另一个元素替换任何数组元素的成本是两者之间的绝对差异。
例子:

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

  • 要有效地找到每个运行子数组的中位数,请使用多重集来获取每个子数组中元素的排序顺序。 Median 将是这个multiset的中间元素
  • 对于下一个子数组,从多重集中删除前一个子数组的最左边的元素,将当前元素添加到多重集中。
  • 保持一个指针mid可以有效地跟踪多重集的中间元素。
  • 如果新添加的元素小于前一个中间元素,则将mid移动到其紧邻较小的元素。否则,将mid移动到其紧邻的下一个元素。
  • 用方程计算替换子数组的每个元素的成本| A[i] – 中值each_subarray | .
  • 最后打印总成本。

下面是上述方法的实现:

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)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。