• Leetcode 870. 优势洗牌(中等) 田忌赛马策略


    labuladong讲解

    870. 优势洗牌(中等)

    题目:

    给你输入两个长度相等的数组 nums1 和 nums2,请你重新组织 nums1 中元素的位置,使得 nums1 的「优势」最大化。

    如果 nums1[i] > nums2[i],就是说 nums1 在索引 i 上对 nums2[i] 有「优势」。优势最大化也就是说让你重新组织 nums1,尽可能多的让 nums[i] > nums2[i]

    比如输入:

    nums1 = [12,24,8,32] nums2 = [13,25,32,11]

    你的算法应该返回 [24,32,8,12],因为这样排列 nums1 的话有三个元素都有「优势」。

    思路:

    我们暂且把田忌的一号选手称为 T1,二号选手称为 T2,齐王的一号选手称为 Q1

    如果 T2 能赢 Q1,你试图保存己方实力,让 T2 去战 Q1,把 T1 留着是为了对付谁?

    显然,你担心齐王还有战力大于 T2 的马,可以让 T1 去对付。

    但是你仔细想想,现在 T2 已经是可以战胜 Q1 的,Q1 可是齐王的最快的马耶,齐王剩下的那些马里,怎么可能还有比 T2 更强的马?

    所以,没必要节约,最后我们得出的策略就是:

    将齐王和田忌的马按照战斗力排序,然后按照排名一一对比。如果田忌的马能赢,那就比赛,如果赢不了,那就换个垫底的来送人头,保存实力。

    将nums1从大到小排序,按照num2从大到小的顺序,逐个比较num1对应位置的大小,如果nums1[left]>nums2,就设为left值,否则设为right值(最小值)

    class Solution {
    public:
        vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
            //记录nums2的值及位置
            priority_queue<Node> q;
            for(int i=0;i<nums2.size();++i){
                q.push(Node(i,nums2[i]));
            }
            //nums1从大到小排序
            sort(nums1.begin(),nums1.end(),[](int a,int b){
                return a>b;
            });
            //使用双指针记录nums1的最大值和最小值
            int left=0,right=nums1.size()-1;
            vector<int> ret(nums1.size());
            for(int i=0;i<nums1.size();++i){
                Node node=q.top();
                q.pop();
                int val=node.val;
                int id=node.id;
                //如果nums1对应位置大于nums2,设为该值
                if(nums1[left]>val){
                    ret[id]=nums1[left++];
                }else{
                    //如果小于,则设为nums1的最小值
                    ret[id]=nums1[right--];
                }
            }
            return ret;
        }
        struct Node{
            int id;
            int val;
            Node(int i,int v){
                id=i;
                val=v;
            }
            //priority_queue默认为大根堆,因此使用less来比较
            bool operator<(const Node& b) const{
                return val<b.val;
            }
        };
    };
  • 相关阅读:
    集合合并
    非递减有序集合合并
    有序的双链表的实现
    单链表的实现
    构造有序的单链表
    约瑟夫环问题
    javaweb学习笔记
    Intellij IDEA快捷键
    JAVA:创建类和对象
    JAVA:成员变量和局部变量的区别
  • 原文地址:https://www.cnblogs.com/zl1991/p/15945123.html
Copyright © 2020-2023  润新知