题目描述
给定两个大小相等的数组 A
和 B
,A
相对于 B
的优势可以用满足 A[i] > B[i]
的索引 i
的数目来描述。
返回 A
的任意排列,使其相对于 B
的优势最大化。
样例
输入:A = [2,7,11,15], B = [1,10,4,11]
输出:[2,11,7,15]
输入:A = [12,24,8,32], B = [13,25,32,11]
输出:[24,32,8,12]
限制
1 <= A.length = B.length <= 10000
0 <= A[i] <= 10^9
0 <= B[i] <= 10^9
算法
(贪心) $O(n \log n)$
- 将
A
和B
数组从小到大排序。 - 在
B
数组上定义双指针l
和r
,初始时l = 0
,r = n - 1
。如果当前A[i] > B[l]
,则我们就这样安排,否则我们安排当前B
最大的数字。 - 贪心的正确性是
A
中的每个数字都要尽可能的干掉B
中的一个数字,如果干不掉,则消耗掉B
中剩余最大的数字。
时间复杂度
- 排序的时间复杂度为 $O(n \log n)$。
- 安排数字的时间复杂度为 $O(n)$。
- 故总时间复杂度为 $O(n \log n)$。
空间复杂度
- 需要 $O(n)$ 的额外空间存储
B
数组的索引和答案。
C++ 代码
class Solution {
public:
vector<int> advantageCount(vector<int>& A, vector<int>& B) {
int n = A.size();
vector<int> idx(n);
for (int i = 0; i < n; i++)
idx[i] = i;
sort(A.begin(), A.end());
sort(idx.begin(), idx.end(), [&](int x, int y) {
return B[x] < B[y];
});
vector<int> ans(n);
for (int i = 0, l = 0, r = n - 1; i < n; i++) {
if (A[i] > B[idx[l]]) ans[idx[l++]] = A[i];
else ans[idx[r--]] = A[i];
}
return ans;
}
};