题目
给定两个大小相等的数组 A 和 B,A 相对于 B 的优势可以用满足 A[i] > B[i] 的索引 i 的数目来描述。
返回 A 的任意排列,使其相对于 B 的优势最大化。
代码
class Solution {
/**
* 类似田忌赛马,对两个数组排序,打得过就打,打不过就用最垃圾的来混
* @param nums1
* @param nums2
* @return
*/
public int[] advantageCount(int[] nums1, int[] nums2) {
int n =nums1.length;
// 给 nums2 降序排序,使用堆来记录num2的索引,不然会打乱了
PriorityQueue<int[]> maxpq = new PriorityQueue<>(
(int[] p1,int[] p2 ) ->{//声名比较器,比较数组的第二个数字
return p2[1]-p1[1];
}
);
for (int i = 0; i <n ; i++) {
maxpq.offer(new int[]{i,nums2[i]});//将num2输入大跟堆
}
// 给 nums1 升序排序
Arrays.sort(nums1);// nums1[left] 是最小值,nums1[right] 是最大值
int left=0,right=n-1;
int[] res =new int[n];
while (!maxpq.isEmpty()){
int[] pair=maxpq.poll();//去除最大的值
int i =pair[0],maxVal=pair[1];// maxval 是 nums2 中的最大值,i 是对应索引
if (maxVal<nums1[right]){//打得过
res[i]=nums1[right];
right--;
}else {//打不过,那最拉的来顶
res[i]=nums1[left];
left++;
}
}
return res;
}
}
要点
- 本题类似田忌赛马,打得过就打,若打不过再用下等马比
- 对两个数组都排序,但num2需要记录索引信息,所以用数组储存,将其送入大跟堆中。
- 实现上用到了双指针技巧,从最快的马开始,比得过就比,比不过就送,这样就能对任意数量的马求取一个最优的比赛策略了。