Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一.题目
870. 优势洗牌 给定两个大小相等的数组
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 <= 100000 <= A[i] <= 10^90 <= B[i] <= 10^9
二、思路分析:
根据题目的要求,需要我们返回A的排列相对于数组B优势最大化,这就需要我们找出一个合理的策略能够满足条件,首先我们需要把数组A的所有元素进行排序,又因为我们不能够对数组B进行排序(因为我们要给出A的排列相对于B优势最大化,即B数组的元素位置不能变),所以我们就需要有个辅助数组来完成比较的工作。
我们想到的策略是:利用升序排列好的数组A与已经降序排列的辅助数组进行比较,在利用双指针指向数组A的最大值和最小值,利用A的最大值与辅助数组的最大值进行比较,如果A的最大值比辅助数组的最大值小,那么我们就用数组A的最小值去对上辅助数组的最大值,这样的操作一直到循环结束,我们就能够确立相对于B的优势最大化。
那么我们产生的问题大概分为2个:
- 如果创建与
数组B关联的数组 - 进行比较后如果进行操作
针对第一个问题我们采取的操作是利用JS的map函数创建关于数组B的索引数组,在利用sort函数对索引代表的数组B的元素进行降序排列,最后进行比较即可。对于第二个问题,我们每次比较,如果数组A中存在的最大值小于索引数组代表的数组B元素,我们我们就将最小值放在结果数组对应的索引上,再将left右移,反之right左移。
三、代码:
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var advantageCount = function(nums1, nums2) {
nums1.sort((a,b)=>a-b)
//res存储答案
let res = []
//A数组升序排列,B数组位置不能变化需要创建一个新数组来辅助数组B
//新创建的数组以降序排列
let indexB = nums2.map((v,i)=>i)
indexB.sort((x,y) => nums2[y]-nums2[x])
//初始化A数组的左右指针
let left = 0
let right = nums2.length-1
for(let i=0 ; i<nums2.length ; i++){
//如果A的最大数比B数组的最大数大,那么将A的最大数推入结果,反之把最小数给结果
if(nums1[right]>nums2[indexB[i]]){
res[indexB[i]] = nums1[right]
right--
}else{
res[indexB[i]] = nums1[left]
left++
}
}
return res
};
四、总结:
对于这种问题的求解方式让我想起了田忌赛马的套路,就是我最大的值比不过你的最大值的时候,我会用我的最次的东西去跟你最好的东西作比较,这种算法也相当于贪心算法,很值得我们去回味。