加载中...
870-优势洗牌(Advantage Shuffle)
发表于:2021-12-03 | 分类: 中等
字数统计: 878 | 阅读时长: 4分钟 | 阅读量:

原文链接: https://leetcode-cn.com/problems/advantage-shuffle

英文原文

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. 1 <= A.length = B.length <= 10000
  2. 0 <= A[i] <= 10^9
  3. 0 <= B[i] <= 10^9

通过代码

官方题解

方法:贪心

思路

如果 A 中最小的牌 a 能击败 B 中最小的牌 b,那么我们应当将它们配对。否则, a 将无益于我们的比分,因为它无法击败任何牌。

我们为什么要在 a > b 时将 ab 配对呢?这是因为此时在 A 中的每张牌都比 b 要大,所以不管我们在 b 前面放置哪张牌都可以得分。我们可以用手中最弱的牌来与 b 配对,这样会使 A 中剩余的牌严格地变大,因此会有更多得分点。

算法

我们可以根据上面的思路来创造一种贪心算法。目前在 B 中要被击败的最小的牌将始终是 b = sortedB[j]。对于在 sortedA 中的每张卡 a,要么 a 能够击败牌 b(将 a 放入 assigned[b]),要么把 a 扔掉(将 a 放入 remaining)。

之后,我们可以使用此前标注的 assignedremaining 来重构答案。详细情况请查阅注释。

[L5ToovSe-Java]
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; } }
[L5ToovSe-Python]
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$ 是 AB 的长度。

  • 空间复杂度:$O(N)$。

统计信息

通过次数 提交次数 AC比率
16084 36968 43.5%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言
上一篇:
871-最低加油次数(Minimum Number of Refueling Stops)
下一篇:
869-重新排序得到 2 的幂(Reordered Power of 2)
本文目录
本文目录