英文原文
You are given two integer arrays nums1
and nums2
both of the same length. The advantage of nums1
with respect to nums2
is the number of indices i
for which nums1[i] > nums2[i]
.
Return any permutation of nums1
that maximizes its advantage with respect to nums2
.
Example 1:
Input: nums1 = [2,7,11,15], nums2 = [1,10,4,11] Output: [2,11,7,15]
Example 2:
Input: nums1 = [12,24,8,32], nums2 = [13,25,32,11] Output: [24,32,8,12]
Constraints:
1 <= nums1.length <= 105
nums2.length == nums1.length
0 <= nums1[i], nums2[i] <= 109
中文题目
给定两个大小相等的数组 A
和 B
,A 相对于 B 的优势可以用满足 A[i] > B[i]
的索引 i
的数目来描述。
返回 A
的任意排列,使其相对于 B
的优势最大化。
示例 1:
输入:A = [2,7,11,15], B = [1,10,4,11] 输出:[2,11,7,15]
示例 2:
输入: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
通过代码
官方题解
方法:贪心
思路
如果 A
中最小的牌 a
能击败 B
中最小的牌 b
,那么我们应当将它们配对。否则, a
将无益于我们的比分,因为它无法击败任何牌。
我们为什么要在 a > b
时将 a
和 b
配对呢?这是因为此时在 A
中的每张牌都比 b
要大,所以不管我们在 b
前面放置哪张牌都可以得分。我们可以用手中最弱的牌来与 b
配对,这样会使 A
中剩余的牌严格地变大,因此会有更多得分点。
算法
我们可以根据上面的思路来创造一种贪心算法。目前在 B
中要被击败的最小的牌将始终是 b = sortedB[j]
。对于在 sortedA
中的每张卡 a
,要么 a
能够击败牌 b
(将 a
放入 assigned[b]
),要么把 a
扔掉(将 a
放入 remaining
)。
之后,我们可以使用此前标注的 assigned
和 remaining
来重构答案。详细情况请查阅注释。
class Solution {
public int[] advantageCount(int[] A, int[] B) {
int[] sortedA = A.clone();
Arrays.sort(sortedA);
int[] sortedB = B.clone();
Arrays.sort(sortedB);
// assigned[b] = list of a that are assigned to beat b
Map<Integer, Deque<Integer>> assigned = new HashMap();
for (int b: B) assigned.put(b, new LinkedList());
// remaining = list of a that are not assigned to any b
Deque<Integer> remaining = new LinkedList();
// populate (assigned, remaining) appropriately
// sortedB[j] is always the smallest unassigned element in B
int j = 0;
for (int a: sortedA) {
if (a > sortedB[j]) {
assigned.get(sortedB[j++]).add(a);
} else {
remaining.add(a);
}
}
// Reconstruct the answer from annotations (assigned, remaining)
int[] ans = new int[B.length];
for (int i = 0; i < B.length; ++i) {
// if there is some a assigned to b...
if (assigned.get(B[i]).size() > 0)
ans[i] = assigned.get(B[i]).pop();
else
ans[i] = remaining.pop();
}
return ans;
}
}
class Solution(object):
def advantageCount(self, A, B):
sortedA = sorted(A)
sortedB = sorted(B)
# assigned[b] = list of a that are assigned to beat b
# remaining = list of a that are not assigned to any b
assigned = {b: [] for b in B}
remaining = []
# populate (assigned, remaining) appropriately
# sortedB[j] is always the smallest unassigned element in B
j = 0
for a in sortedA:
if a > sortedB[j]:
assigned[sortedB[j]].append(a)
j += 1
else:
remaining.append(a)
# Reconstruct the answer from annotations (assigned, remaining)
return [assigned[b].pop() if assigned[b] else remaining.pop()
for b in B]
复杂度分析
时间复杂度:$O(N \log N)$,其中 $N$ 是
A
和B
的长度。空间复杂度:$O(N)$。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
16084 | 36968 | 43.5% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|