【LeetCode刷题】NO.14

132 阅读1分钟

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

二、思路分析:

根据题目的要求,需要我们返回A的排列相对于数组B优势最大化,这就需要我们找出一个合理的策略能够满足条件,首先我们需要把数组A的所有元素进行排序,又因为我们不能够对数组B进行排序(因为我们要给出A的排列相对于B优势最大化,即B数组的元素位置不能变),所以我们就需要有个辅助数组来完成比较的工作。

我们想到的策略是:利用升序排列好的数组A与已经降序排列的辅助数组进行比较,在利用双指针指向数组A的最大值和最小值,利用A的最大值与辅助数组的最大值进行比较,如果A的最大值比辅助数组的最大值小,那么我们就用数组A的最小值去对上辅助数组的最大值,这样的操作一直到循环结束,我们就能够确立相对于B的优势最大化。

那么我们产生的问题大概分为2个:

  1. 如果创建与数组B关联的数组
  2. 进行比较后如果进行操作

针对第一个问题我们采取的操作是利用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
};

四、总结:

对于这种问题的求解方式让我想起了田忌赛马的套路,就是我最大的值比不过你的最大值的时候,我会用我的最次的东西去跟你最好的东西作比较,这种算法也相当于贪心算法,很值得我们去回味。