持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情
每日刷题 2022.10.29
- leetcode原题链接:leetcode.cn/problems/ad…
- 难度:中等
题目
- 给定两个大小相等的数组
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]
提示
- 1 <= nums1.length <= 10^5
- nums2.length == nums1.length
- 0 <= nums1[i], nums2[i] <= 10^9
解题思路
- 将
nums2
数组作为基准,来排序nums2
数组,使用二分找到nums1
中第一个大于当前的nums2
的值,将其放到对应的位置上即可。 - 这个题最主要的思考点是:
B
升序排序后,遍历B
,在A
中寻找大于B
单个数字的最小值 - 因此具体步骤如下:
A
和B
先进行升序排序;- 遍历
B
,然后从A
中寻找大于每个B
数值的最小数值,无用数值用数组存储备用。这里对A
的遍历位置做记忆处理; - 获取到可用值和无用值后,再对
B
副本进行遍历(顺序要和排序前的B
保持一致),有可用值就用,无可用值就用无用值做备胎.
AC
代码
var advantageCount = function(nums1, nums2) {
nums1.sort((a, b) => a - b);
let n = nums2.length, ans = [], map = new Map(), set = new Set();
for(let i = 0; i < n; i++) {
let idx = binary(nums2[i]);
if(idx === -1) ans.push(-1);
else {
ans.push(nums1[idx]);
map.set(idx, 1)
set.add(idx);
}
}
let use = [];
// 还需要处理,当不存在的时候,需要将没有用过的填充进去
for(let i = 0; i < n; i++) {
if(!set.has(i)) use.push(i);
}
for(let i = 0, tar = 0; i < n; i++) {
if(ans[i] === -1) {
ans[i] = nums1[use[tar++]];
}
}
return ans;
function binary(cur) {
let l = -1, r = n;
while(l + 1 != r) {
let mid = (l + r) >>> 1;
if(nums1[mid] <= cur) {
l = mid;
}else {
r = mid;
}
}
if(map.has(r)) {
// 当前的已经被使用过
while(r < n) {
r++;
if(!map.has(r)) break;
}
}
if(r === n) return -1;
return r;
}
};