JavaScript算法11-优势洗牌

一、问题描述

给定两个大小相等的数组 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

二、解题方法

2.1 田忌赛马

拿到题目的第一想法:emmm,这不纯纯田忌赛马的代码版吗?先给马儿分个等级,然后挨个pk,打的过就打,打不过的就去打别人最好的马。按照这个思路有以下几个步骤:

  • 给数组nums1和nums2进行升序排序
  • 使用排序后的数组进行两两比较,当数组nums1中的第一个元素可以大于nums2中第一个元素时,优势加一,两数组第一项都排除(也就是不再进行比较);
  • 若是nums1第一个元素<=nums2第一个元素,则需要将nums1的第一个元素与nums2的最后一个元素进行比较(nums1最小的元素(劣等马)PK nums2最大的元素(上等马)),再移除nums1第一个元素和nums2第一个元素;
  • 在实际的代码编写中,我们无需真正地「移除」元素。对于 nums1​,我们使用一个循环依次遍历其中的每个元素;对于 nums2,我们可以使用双指针 left和 right。如果 nums1的首个元素可以增加「优势」,就配对 left对应的元素并向右移动一个位置;如果无法配对,就配对 right 对应的元素并向左移动一个位置。
    代码如下:
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var advantageCount = function(nums1, nums2) {
    const n=nums1.length;
    //idx记住两个数组的下标索引值
    const idx1=new Array(n).fill(0);
    const idx2=new Array(n).fill(0);
    for(let i=0;i<n;++i){
        idx1[i]=i;
        idx2[i]=i;
    }
    //根据原数组的大小,重新排列idx中的下标索引,这样在之后根据idx值在数组中取数时,
    //是按照升序顺序取数的,相当于对原数组做了一个排序
    //sort中比较函数是>0就交换前后位置,这里需要注意一下
    // eg:nums1[i]-nums1[j]>0,则交换数组idx1中的i、j
    idx1.sort((i,j)=>nums1[i]-nums1[j]);
    idx2.sort((i,j)=>nums2[i]-nums2[j]);

    const ans=new Array(n).fill(0);
    //left记录nums2中的位置,要是nums1中首位可以增加优势,则配对left指向的元素并人left右移一位
    //要是不能增加优势,则配对right指向的元素并让right左移一位
    let left=0,right=n-1;
    for(let i=0;i<n;++i){
        if(nums1[idx1[i]]>nums2[idx2[left]]){
            ans[idx2[left]]=nums1[idx1[i]];
            ++left;
        }else{
            ans[idx2[right]]=nums1[idx1[i]];
            --right;
        }
    }
    return ans;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值