【Java刷题 25-2】LeetCode:870. 优势洗牌

106 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第 天,点击查看活动详情


题目、870. 优势洗牌

原题链接:870. 优势洗牌

题目描述

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

解题思路

需要让优势最大化,我们首先记录下两个数组原始的下标位置,然后给两个数组排序,借此让优势最大化。

因为当我们排序后,比较nums1 与 nums2 的首元素,当nums1元素 大于 nums2 元素,就能形成优势,而这时候因为排序了的缘故,nums1后面的元素都是大于nums2首元素的,这让便于让优势最大化。

当我们的nums1首元素与nums2首元素比较发现较小而没有优势时,我们就能直接删除掉nums1元素,因为此元素依旧无法形成优势了,原因与上一段一样,我们可以将它与nums2中的尾部最大元素对应。同时nums2尾部元素也可以删除。

一直冲下去,到最后就能得到一个优势最大化的数组,直接返回即可。

提交代码

class Solution {
    public int[] advantageCount(int[] nums1, int[] nums2) {
        int n = nums1.length;            //获取数组的长度
        Integer[] idx1 = new Integer[n]; //创建包装类Integer数组,因为可以设置比较器
        Integer[] idx2 = new Integer[n];
        for (int i = 0; i < n; ++i) {    //记录两个数组的下标位置
            idx1[i] = i;
            idx2[i] = i;
        }
        //调用Arrays的sort()排序方法
        Arrays.sort(idx1, (i, j) -> nums1[i] - nums1[j]);//将数组由小到大排序
        Arrays.sort(idx2, (i, j) -> nums2[i] - nums2[j]);

        int[] ans = new int[n];           //创建数组,存放优势最大化数组
        int left = 0, right = n - 1;      //记录左右下标
        for (int i = 0; i < n; ++i) {     //遍历两个排序好的数组
        //只需要对比首个元素
            if (nums1[idx1[i]] > nums2[idx2[left]]) { // 如果nums1当前元素更大
            //代表后面的数字也会比nums2当前元素大,可以让优势最大化
                ans[idx2[left]] = nums1[idx1[i]];
                ++left;
            } else {//如果nums1元素较小,那就删除当前元素,向后移动
                ans[idx2[right]] = nums1[idx1[i]];//将删除的较小元素与nums2最大元素对照
                --right;                     
            }
        }
        return ans;    //返回优势最大化数组
    }
}

提交结果

在这里插入图片描述