地址:
力扣https://leetcode-cn.com/problems/advantage-shuffle/
题目:
给定两个大小相等的数组 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/advantage-shuffle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
本题其实就是田忌赛马
对于 A ,B 两个数组,有可能 升序后, A 全部都大于 B;也有可能部分大于或者完全不大于
以 A = [12,24,8,32], B = [13,25,32,11] 为例子:
排序后 A =[8,12,24,32],B =[11,13,25,32] 部分大于
我们来推演过程:
1. A[0] =8 与 B[0] = 11 比较,不满足A > B,忽略 A 的 8
2. A 的下一个元素继续比较,大于,那么匹配成一对
3. 同理,后续匹配情况
4. 最后一定剩余不匹配的,这个时候无所谓,依序匹配就是
整个匹配按照 A 元素依序比较 B 元素,因为做了排序,所以是在 A 元素的最小值刚好大于 B 元素的匹配。如果拿更大的A匹配B,就不划算。
方法一、贪心
最后的输出一定是按照 B 的原始序号匹配输出,但是我们的比较是做了排序的,那么势必要保存 B 的原始序号,所以自定义个结构体来保存 B 的信息。
最后匹配信息也会填入这个结构体,全部完成后,再依据 存的 idx 栏位升序排列,输出匹配的值即可
typedef struct {
int val; // orig val
int idx; // orig idx
int mval; // matched val
}KEYVAL;
int cmpKeyVal(const KEYVAL *a, const KEYVAL *b)
{
return a->val - b->val;
}
int cmpKeyIdx(const KEYVAL *a, const KEYVAL *b)
{
return a->idx - b->idx;
}
int cmpInt(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
void dispKeyvalArr(KEYVAL *arr, int arrlen)
{
for(int i=0; i<arrlen; i++)
printf("val=%d,idx=%d,mval=%d\n", arr[i].val, arr[i].idx, arr[i].mval);
}
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* advantageCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
int i,j;
KEYVAL *bArr = (KEYVAL *)malloc(sizeof(KEYVAL) * nums2Size);
for(i=0; i<nums2Size; i++)
{
bArr[i].val = nums2[i];
bArr[i].idx = i;
bArr[i].mval = -1;
}
//dispKeyvalArr(bArr, nums2Size);
// sore by val
qsort(bArr, nums2Size, sizeof(KEYVAL), cmpKeyVal);
//dispKeyvalArr(bArr, nums2Size);
qsort(nums1, nums1Size, sizeof(int), cmpInt);
// for(i=0; i<nums1Size; i++)
// {
// printf("nums1[%d]=%d\n", i, nums1[i]);
// }
int k = 0;
int umNum = 0; // un-matched number
for(i=0, j=0; i<nums1Size; i++)
{
if(nums1[i] <= bArr[j].val)
{
//printf("unmatch...nums1[%d]=%d, bArr[%d].val=%d\n", i, nums1[i], j, bArr[j].val);
nums2[k++] = nums1[i]; // re-use nums2 to restore un-match elements
umNum++;
}
else
{
bArr[j++].mval = nums1[i];
}
}
k = 0;
while(umNum--)
{
bArr[j++].mval = nums2[k++];
}
//dispKeyvalArr(bArr, nums2Size);
// sore by idx
qsort(bArr, nums2Size, sizeof(KEYVAL), cmpKeyIdx);
//dispKeyvalArr(bArr, nums2Size);
// return new nums1
for(i=0, j=0; i<nums1Size; i++)
nums1[i] = bArr[i].mval;
*returnSize = nums1Size;
return nums1;
}