先决条件:滑动窗口中位数
给定一个由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
方法:
要找到将子数组的每个元素转换为单个元素的最小成本,请将子数组的每个元素更改为该子数组的中值。请按照以下步骤解决问题:
- 要有效地找到每个运行子数组的中位数,请使用多重集来获取每个子数组中元素的排序顺序。 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 现场工作专业课程和学生竞争性编程现场课程。