870. 优势洗牌

前言

这道题有下标数组的使用,建议先做:

按身高排序

解析:

按身高排序的解法

题目描述

给定两个长度相等的数组 n u m s 1 nums1 nums1 和 n u m s 2 nums2 nums2, n u m s 1 nums1 nums1 相对于 n u m s 2 nums2 nums2 的优势可以用满足 n u m s 1 i > n u m s 2 i nums1i > nums2i nums1i>nums2i 的索引 i i i 的数目来描述

返回 n u m s 1 nums1 nums1 的任意排列,使其相对于 n u m s 2 nums2 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

解法

这是一个田忌赛马的问题,田忌赛马指的是,田忌有上、中、下等马,齐威王有上、中、下等马,齐威王的上等马比田忌的上等马好,其它的也是这样

当田忌以下面的方式对位时,就会失败:

当田忌以另一种方式对位时,就能获胜:

这里就衍生出了一种思想,先将两个人的马按照实力升序排序:

田忌的下等马无法赢过齐威王的所有马,所以让它去拖累齐威王的上等马

田忌的中等马最低能赢过齐威王的下等马,所以让它和齐威王的下等马比

田忌的上等马最低能赢过齐威王的中等马,所以让它和齐威王的中等马比

此时就会得到前一张图的结果

这道题目就用到了这种思想,先将两个数组 n u m s 1 nums1 nums1 和 n u m s 2 nums2 nums2 排升序,定义 l e f t left left 指向 n u m s 2 nums2 nums2 的开头, r i g h t right right 指向 n u m s 2 nums2 nums2 的末尾:

  • n u m s i < = n u m s 2 l e f t numsi <= nums2left numsi<=nums2left 时,说明比不过,让它去拖累最大值, r e t r i g h t = n u m s i , r i g h t − − retright = numsi, right-- retright=numsi,right−−
  • n u m s i > n u m s 2 l e f t numsi > nums2left numsi>nums2left 时,说明比得过,让它进行比较, r e t l e f t = n u m s i , l e f t + + retleft = numsi, left++ retleft=numsi,left++

最终得到结果:

看起来和题目要的答案不同,因为结果中的数据,对应的是排了升序的 n u m s 2 nums2 nums2 中的数据。如果想在不影响映射关系的情况下排序,可以创建一个下标数组,对下标数组进行排序

代码

cpp 复制代码
class Solution {
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) 
    {
        vector<int> indices(nums1.size());
        for (int i = 0;i < indices.size();++i)
        {
            indices[i] = i;
        }

        sort(indices.begin(), indices.end(), [&](int i, int j){
            return nums2[i] < nums2[j];
        });
        sort(nums1.begin(), nums1.end());

        vector<int> ret(nums1.size());
        int left = 0, right = indices.size() - 1;
        for (int i = 0;i < nums1.size();++i)
        {
            if (nums1[i] <= nums2[indices[left]])
            {
                ret[indices[right]] = nums1[i];
                right--;
            }
            else
            {
                ret[indices[left]] = nums1[i];
                left++;
            }
        }
        return ret;
    }
};
相关推荐
Logic1011 天前
C语言/数据结构贪心算法题解:字符串趋同——逐位统计最高频率求最小修改代价
c语言·数据结构·贪心算法·字符串·时间复杂度·频率统计·算法题
-dzk-3 天前
【贪心算法】LC 55.跳跃游戏
算法·游戏·贪心算法
-dzk-3 天前
【贪心算法】LC 763.划分字母区间
算法·贪心算法
Zhu7585 天前
离线二进制部署-Kubernetes-v1.36.4
容器·贪心算法·kubernetes
Elastic 中国社区官方博客5 天前
Kubernetes attributes processor v1:它对 EDOT Collector 意味着什么
java·大数据·elasticsearch·搜索引擎·贪心算法·kubernetes·全文检索
Doubbbbbbble云6 天前
基于贪心算法的区间覆盖问题求解策略4
算法·贪心算法
Cccp.1237 天前
【leetcode】(七)前缀树和贪心算法
数据结构·leetcode·贪心算法
-森屿安年-7 天前
买卖股票的最佳时机
c++·贪心算法
-森屿安年-15 天前
返回最大数
c++·贪心算法