算法小知识-----10.16----- 优势洗牌

76 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

优势洗牌

该题出自力扣的870题 —— 优势洗牌【中等题】

审题

给定两个大小相等的数组 nums1 和 nums2,nums1 相对于 nums2 的优势可以用满足 nums1[i] > nums2[i] 的索引 i 的数目来描述。 返回 nums1 的任意排列,使其相对于 nums2 的优势最大化。

image.png

  • 该题虽然是中等题,但是题意也算简单,没有过分复杂

  • 给出两个整型数组,对第一个数组进行排序后,返回第一个数组,并且第一个数组需要每个元素大于第二个数组

  • 总结这道题的题意就是,田忌赛马,每次找出比数组2中大数组1的最小值,并且返回,如果没有,则直接返回数组1的值

  • 定义两个数组,装箱后的Integer型是为了使用比较器,直接Arrays.sort排序,并且填充下标后,对应的排序值

  • 定义返回的数组,定义两个指针

  • 把 nums1当成是田忌的马,nums2 当成是齐威王的马,讨论田忌的下等马nums1的最小值

  • 如果num比nums2中的最小值大,则本次res中num对应的下标为index[left],然后left++

  • 否则本次res中num对应的下标为index[right],然后right--

  • 计数操作容易想到哈希表,而实时维护候选集合并高效查询可以使用基于红黑树的 TreeSet 数据结构。

编码

class Solution {
    public int[] advantageCount(int[] nums1, int[] nums2) {
        int len = nums1.length;
        Integer[] a = new Integer[len];
        Integer[] b = new Integer[len];
        for (int i = 0; i < len; i++) {
            a[i] = i;
            b[i] = i;
        }
        Arrays.sort(a, Comparator.comparingInt(i -> nums1[i]));
        Arrays.sort(b, Comparator.comparingInt(i -> nums2[i]));
        int[] ans = new int[len];
        int left =0,right = len -1;
        for (int i = 0; i < len; i++) {
            if (nums1[a[i]] > nums2[b[left]]){
                ans[b[left]] = nums1[a[i]];
                left++;
            }else {
                ans[b[right]] = nums1[a[i]];
                --right;
            }
        }
        return ans;
    }
}

image.png