力扣 每日一题 870. 优势洗牌难度:中等,rating: 1648(贪心+双指针)

Posted nefu-ljw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣 每日一题 870. 优势洗牌难度:中等,rating: 1648(贪心+双指针)相关的知识,希望对你有一定的参考价值。

题目链接

https://leetcode.cn/problems/advantage-shuffle/

题目来源于:第 93 场周赛 Q3 rating: 1648

思路

贪心、双指针。

贪心策略类似于田忌赛马(大的匹配大的,匹配不上就用小的匹配大的)。

首先,肯定要把nums1, nums2排序,对于nums2还要额外记一下排序前的原坐标(可以用pair存到vector里面),存入s2。

然后,以下图为例,用双指针i, j比较两个数组尾部的大小,逆序遍历s2,如果nums1>s2,那么直接匹配上;反之,则将s2匹配上nums1的首部,这个首部的坐标可以再加一个指针k来维护。

代码

class Solution 
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) 
        sort(nums1.begin(),nums1.end());

        vector<pair<int,int>> s2;
        int n=nums1.size();
        for(int i=0;i<n;i++)
            s2.push_back(make_pair(nums2[i],i));
        
        sort(s2.begin(),s2.end()); // 先根据pair中的first排序,若fisrt相同再按second排序

        vector<int> ans(n);
        int i=n-1; // i是nums1的尾部下标
        int k=0; // k是nums1的首部下标
        for(int j=n-1;j>=0;j--) // 逆序遍历s2,j是s2的下标
            int pos=s2[j].second;
            int val=s2[j].first;
            if(nums1[i]>val) // 若当前nums1的尾部比当前s2大
                ans[pos]=nums1[i]; // s2匹配nums1的尾部
                i--;
            else
                ans[pos]=nums1[k]; // s2匹配nums1的首部
                k++;
            
        
        assert(k==i+1);
        return ans;
    
;

/*
[0,1,2,2,4]
[0,0,1,2,3]
ans: [1,2,2,0,4]
*/

以上是关于力扣 每日一题 870. 优势洗牌难度:中等,rating: 1648(贪心+双指针)的主要内容,如果未能解决你的问题,请参考以下文章

每日一题870. 优势洗牌

力扣 每日一题 811. 子域名访问计数难度:中等

力扣 每日一题 934. 最短的桥难度:中等,rating: 1825(dfs / bfs)

力扣 每日一题 856. 括号的分数难度:中等(栈 / 思维计数&括号深度)

力扣 每日一题 811. 子域名访问计数难度:中等,rating: 1377(字符串切分+哈希表计数)

力扣 每日一题 777. 在LR字符串中交换相邻字符难度:中等,rating: 1938(思维)