问题
Assuming I have two arrays A and B (Both with equal number of elements)
int A[] = {40,50,70};
int B[] = {80,60,45};
I have to rearrange array A in such a way that maximum number of elements in Array A are greater than their respective elements in array B.
In this case, rearranging A as {40,70,50} would yield the required result.
What would be the most optimal way of going this?
回答1:
I would use something like:
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;
}
Demo
Complexity: O(n log n)
.
回答2:
Assume that we can also rearrange B for now. Clearly, it's always optimal to match the largest elements in A to lesser elements in B. Therefore, we can iterate over elements in A in decreasing order and try to pair them with lesser elements in B.
For each element in A, we'll want to use the greatest unused element in B which is less than the element in A, since we want to save the smaller elements in B for use later. We can sort B and find this element using binary search or by maintaining a pointer to the greatest unused element. If at any point we can't find an unused element in B that is less than the next element in A, we know that we won't be able to match the rest of the elements in A to lesser elements in B so we can match the remaining elements arbitrarily. Now we can rearrange the pairs so that the elements in B will be in their original order and we have a solution.
来源:https://stackoverflow.com/questions/61160415/arrangement-of-arrays-such-that-maximum-number-of-elements-are-greater-in-one-ar