题目:优势洗牌
给定两个大小相等的数组 nums1 和 nums2,nums1 相对于 nums2 的优势可以用满足 nums1[i] > nums2[i] 的索引 i 的数目来描述。
返回 nums1 的任意排列,使其相对于 nums2 的优势最大化。
示例 1:
输入: nums1 = [2,7,11,15], nums2 = [1,10,4,11]
输出: [2,11,7,15]
示例 2:
输入: nums1 = [12,24,8,32], nums2 = [13,25,32,11]
输出: [24,32,8,12]
提示:
nums2.length == nums1.length
解题思路
核心思路是将两个数组都进行排序,然后每次用nums1中未被排列的最大值去和nums2中未被比较的最大值进行比较,赢了就放在相应位置上,输了就把nums1中未被排列的最小值放在相应位置上。
怎样知道nums1中未被排列的最大值和最小值?
因为数组nums1经过排序,对于有序数组,只需要使用双指针来记录未被排列的边界即可。 怎样知道相应位置的索引?
相应位置就是nums2中未被比较过的最大值对应的索引,所以不能直接对nums2中的元素进行排序,需要带着索引进行排序。另外,每次需要取出最大值,自然而然想到了大根堆。因此利用PriorityQueue的定制排序可以轻松实现。
对于num2中的每一个元素,在num1中找到一个比它大的元素即可。这样的话思路很清晰,直接对两个数组进行循环遍历,然后找到对应的值。
代码实现
public int[] advantageCount(int[] nums1, int[] nums2) {
int n = nums1.length;
//nums1 从小到大排序
Arrays.sort(nums1);
// nums2 从大到小排序(带上索引)
PriorityQueue < int[] > n2Sorted = new PriorityQueue < > (
(a, b) - > {
return b[1] - a[1];
}
);
for (int i = 0; i < nums2.length; i++) {
n2Sorted.offer(new int[] {
i, nums2[i]
});
}
int[] res = new int[n];
// 左右指针记录nums1中没被排列过的元素
int left = 0;
int right = n - 1;
while (!n2Sorted.isEmpty()) {
int[] n2 = n2Sorted.poll();
if (nums1[right] > n2[1]) {
res[n2[0]] = nums1[right--];
} else {
res[n2[0]] = nums1[left++];
}
}
return res;
}
运行结果
复杂度分析
- 空间复杂度:O(n)
- 时间复杂度:O(n)
在掘金(JUEJIN) 一起分享知识, Keep Learning!