先决条件:滑动窗口中位数
给定一个由N个整数和一个整数K组成的数组arr [] ,任务是找到使长度为K的每个子数组的每个元素相等所需的最小成本。用另一个元素替换任何数组元素的成本是两者之间的绝对差。
例子:
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
方法:
若要找到将子数组的每个元素转换为单个元素的最低成本,请将子数组的每个元素更改为该子数组的中位数。请按照以下步骤解决问题:
- 若要有效地找到每个正在运行的子数组的中位数,请使用多集获取每个子数组中元素的排序顺序。中位数将是此多集的中间元素。
- 对于下一个子数组,请从多集中删除上一个子数组的最左边元素,然后将当前元素添加到多集中。
- 将指针保持在中间,以有效地跟踪多组的中间元素。
- 如果新加入的元素是比以前的中量元素更小,移动中旬到其直接更小的元素。否则,请移至其下一个元素的中间。
- 计算用等式替换子数组的每个元素的成本| 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)