记录一下如何在排序后将原数组下标和排序后数组下标相关联
题目:给定两个大小相等的数组
nums1
和
nums2
,
nums1
相对于
nums2
的优势可以用满足
nums1[i] > nums2[i]
的索引 i 的数目来描述。
返回 nums1
的任意排列,使其相对于 nums2
的优势最大化。
解法:作为一道middle题,思路其实并不难,就是使用贪心算法,先将nums1
和 nums2
排序,再用nums1
中最小的值去匹配nums2
中的最小的值。如果nums1[i] > nums2[i]
,那么将这个nums1
中的值放到答案数组中正确的(即在nums2
中的真实位置),如果小于等于,那么就放到nums2
的队尾。但是难点是如何将当前的符合第一种条件的nums1
中的数放到nums2
中的正确位置,即如何将大小顺序关联到数组中的真实位置,官方题解给了一种巧妙的解法:
class Solution {
public:
vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
vector<int> idx1(n), idx2(n);
//使用一个下标数组,并且使用nums1和nums2来编写sort函数以实现关联
iota(idx1.begin(), idx1.end(), 0);
iota(idx2.begin(), idx2.end(), 0);
sort(idx1.begin(), idx1.end(), [&](int i, int j) { return nums1[i] < nums1[j]; });
sort(idx2.begin(), idx2.end(), [&](int i, int j) { return nums2[i] < nums2[j]; });
vector<int> ans(n);
int left = 0, right = n - 1;
for (int i = 0; i < n; ++i) {
if (nums1[idx1[i]] > nums2[idx2[left]]) {
ans[idx2[left]] = nums1[idx1[i]];
++left;
}
else {
ans[idx2[right]] = nums1[idx1[i]];
--right;
}
}
return ans;
}
};
iota函数: 对于一个范围内的数组依次增加1的赋值