问题描述:
来源:Leetcode第870题
难度:中等
给定两个大小相等的数组A和B,A相对于B的优势可以用满足A[i]>B[i]的索引i的数目 来描述。
返回A的任意排列,使其相对于B的优势最大化。
实例1:
输入:A = [2,7,11,15], B = [1,10,4,11] 输出:[2,11,7,15]
实例2:
输入:A = [12,24,8,32], B = [13,25,32,11] 输出:[24,32,8,12]
提示:
1 <= A.length = B.length <= 10000
0 <= A[i] <= 10^9
0 <= B[i] <= 10^9
问题分析:
题目意思:在A的某一元素大于B的相同位置的元素 即为一个优势。
若把题中的数组长度定为3 则 是经典的田忌赛马问题。但解决方法都是一样的,可以按田忌赛马的问题来解决。
数组A看作田忌的马,数组B看作齐公的马,数值表示马跑的速度。若我们想让田忌胜过齐公:
1,若田忌跑的最快的马比齐公最快的马跑的快,就用田忌最快的马和齐王最快的马比赛。
2,若田忌最快的马还没有齐王最快的马跑的快,就用田忌最慢的马和齐王最快的 马比赛。
第二种方案很好理解,跑不赢最快的马,就用最慢的马作为“炮灰”与最快的马比赛。
第一种方案如果田忌最快的马跑的比齐王最快的马还要快,我们能不能用田忌第 二快的马和齐王最快的马比较呢,其实没必要的。
1,如果田忌第二快的马跑的比齐王最快的马还要快,也就是说田忌最快的前两匹马 和齐王的任何一匹马比赛都能获胜,我们就用田忌最快的马和齐王最快的马比赛 就行了。
2,如果田忌第二快的马没有齐王最快的马跑的快,我们只能用田忌最快的马和齐王 最快的马比赛。
所以不管田忌第二快的马有没有齐王最快的马跑的快,当田忌最快的马跑的比齐王最快 的马还要快的时候,我们就用田忌最快的马和齐王最快的马比赛就行了。
详细代码如下:
class Solution {
public:
vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2)
{
int len=nums1.size();
vector<int> res(len,0);
//容器v 用来存储nums2的原始数组元素以及元素下标
vector<pair<int,int>> v(len);
for(int i=0;i<len;i++)
{
v[i]={nums2[i],i};
}
//对nums1 进行从大的到小排序 ,这里使用的是优先队列,也就是最大堆,每次出队
//的都是堆中最大的元素。
//对V(nums2)进行从小到大排序
sort(nums1.begin(),nums1.end(),greater<int>());
sort(v.begin(),v.end());
//双指针,分别指向nums1 的最大值 和最小值。可以类比于田忌跑的
//最慢的马和跑的最快的马
int left=0,right=len-1;
for(int i=len-1;i>=0;i--)
{
int val=v[i].first;
int index=v[i].second;
//用nums1 的最大值和nums2(v)的最大值比较 即田忌最好的马和齐公最好的马比赛
if(nums1[left]>val)
{
//如果田忌最好的马跑的比齐王最好的马跑的快,
//就用田忌最好的马和齐王最好的马比赛
res[index]=nums1[left];
left++;
}
else
{
//如果田忌最好的马没有齐王最好的马跑的快,就用田忌最差的马
//和齐王最好的马比赛
res[index]=nums1[right];
right--;
}
}
return res;
}
};
同时,由于最终结果要与原始的nums2的顺序对应,所以需要用 v存储 nums2 的原始数据以及下标。
版权声明:本文为m0_63901241原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。