持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
刷题的日常-2022年10月8号
一天一题,保持脑子清爽
优势洗牌
来自leetcode的 870 题,题意如下:
给定两个大小相等的数组nums1和nums2,nums1相对于 nums的优势可以用满足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]
理解题意
我们可以从题意中提取的条件如下:
- 题目给出两个数组
- 要求我们返回nums1的重排序
- 要求nums1[i] > nums2[i]占大多数
做题思路
这道题让我想到了田忌赛马,其实就是用比较大的数去匹配刚刚好超过nums2中的数,抛弃掉比较小的数。规则如下:
- 将两个数组进行排序
- 从前往后遍历nums2
- 在nums1中选出刚好超过nums2的第一个数,没有匹配的放入待匹配列表
- 最后将待匹配理解放回数组中,这部分是不符合条件的
以上规则有个问题,就是需要对nums2进行排序,而题目不允许对nums2进行操作,所以我们可以开辟一个空间进行排序,步骤如下:
- 开辟两个优先级队列对nums1和nums2进行排序
- 再开辟个列表进行保存不能匹配的数
- 将nums1和nums2进行排序,这里nums2的队列保存的是索引,但是排序规则还是按数的大小进行的
- 对nums1的数逐个取出匹配,能够匹配到的放到nums1中对应的nums2的索引位置
- 不匹配的放入最后的列表
- 最后将剩下的数据放入未放置的地方即可
代码实现
代码实现如下:
public class Solution {
public int[] advantageCount(int[] nums1, int[] nums2) {
Queue<Integer> numQueue = new PriorityQueue<>();
Queue<Integer> idxQueue = new PriorityQueue<>(Comparator.comparingInt(o -> nums2[o]));
Queue<Integer> left = new LinkedList<>();
for (int i = 0; i < nums1.length; i++) {
numQueue.add(nums1[i]);
idxQueue.add(i);
}
while (!numQueue.isEmpty()) {
Integer num = numQueue.poll();
int current = nums2[idxQueue.peek()];
if (num > current) {
nums1[idxQueue.poll()] = num;
continue;
}
left.add(num);
}
while (!idxQueue.isEmpty()) {
nums1[idxQueue.poll()] = left.poll();
}
return nums1;
}
}