假设我有两个数组 A 和 B(长度相同):
int A[] = {40,50,70};
int B[] = {80,60,45};
我需要重新排列数组A,使得数组A中比数组B中对应元素大的元素数量最大。
在这种情况下,将A重新排列为{40,70,50}将产生所需的结果。
如何以最优的方式实现此目标?
int A[] = {40,50,70};
int B[] = {80,60,45};
我需要重新排列数组A,使得数组A中比数组B中对应元素大的元素数量最大。
在这种情况下,将A重新排列为{40,70,50}将产生所需的结果。
如何以最优的方式实现此目标?
std::vector<int> f(std::vector<int> A, const std::vector<int>& B)
{
std::vector<std::size_t> indexes(B.size());
std::iota(indexes.begin(), indexes.end(), 0);
std::sort(A.begin(), A.end(), std::greater<>{});
std::sort(indexes.begin(), indexes.end(),
[&B](std::size_t lhs, std::size_t rhs){ return B[lhs] > B[rhs]; });
auto it = A.begin();
auto rit = A.rbegin();
std::vector<int> res(A.size());
for (auto index : indexes) {
if (*it > B[index]) {
res[index] = *it;
++it;
} else {
res[index] = *rit;
++rit;
}
}
return res;
}
复杂度:O(n log n)
。
假设我们现在也可以重新排列B。显然,将A中最大的元素与B中较小的元素匹配始终是最优的。因此,我们可以按照递减顺序迭代A中的元素,并尝试将它们与B中较小的元素配对。
对于A中的每个元素,我们希望使用B中最大的未使用元素,该元素小于A中的元素,因为我们希望将B中较小的元素留到后面使用。我们可以对B进行排序,并使用二分查找或通过维护指向最大未使用元素的指针来找到这个元素。如果我们无法找到一个未使用的B元素,该元素小于A中的下一个元素,则我们知道我们将无法将A中的其余元素与B中较小的元素匹配,因此我们可以任意匹配剩余的元素。现在,我们可以重新排列这些配对,使得B中的元素保持原始顺序,从而得到一个解决方案。