前言
在刷题中学习语言.
2022/10/8
leetcode每日一题:
题目代号 870
问题描述:
优势洗牌//田忌赛马
输入输出示例
问题解析:
- 田忌赛马,需要对双方数组进行排序
- 依照排序的结果调整数组num1
- 由于num2顺序不变,故不可对num2直接排序,
- 建立下标数组,依照num2的数据对下标数组排序
实现代码:
官方题解
class Solution {
public:
vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
vector<int> idx1(n), idx2(n);
iota(idx1.begin(), idx1.end(), 0);//iota() 用于填充容器
iota(idx2.begin(), idx2.end(), 0);
sort(idx1.begin(), idx1.end(), [&](int i, int j) { return nums1[i] < nums1[j]; });//自定义规则,依照nums1的大小排序下标数组
sort(idx2.begin(), idx2.end(), [&](int i, int j) { return nums2[i] < nums2[j]; });
vector<int> ans(n);
int left = 0, right = n - 1;//定义双指针以获取num2未匹配数字的最大最小值
for (int i = 0; i < n; ++i) {
if (nums1[idx1[i]] > nums2[idx2[left]]) {
ans[idx2[left]] = nums1[idx1[i]];
++left;
}
else {//田忌赛马,排序后的nums1的可用最小数小于nums2未匹配数字最小数时,使该最小数对应num2的最大数,以达到全局的最大优势
ans[idx2[right]] = nums1[idx1[i]];
--right;
}
}
return ans;
}
};
我的题解
仅就题目而言,可直接对num1进行排序,无需num1的下标数组
虽然减少了内存的消耗,但影响了num1原数组的数据
实际应用中不建议使用
class Solution {
public:
vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
int n = nums2.size();
vector<int> idx(n);
iota(idx.begin(), idx.end(), 0);
sort(nums1.begin(),nums1.end());//直接对num1进行排序
sort(idx.begin(), idx.end(), [&](int i, int j) { return nums2[i] < nums2[j]; });
vector<int> res(n);
int left = 0, right = n - 1;
for (int i = 0; i < n; ++i) {
if (nums1[i] > nums2[idx[left]]) {
res[idx[left]] = nums1[i];
++left;
}
else {
res[idx[right]] = nums1[i];
--right;
}
}
return res;
}
};
测试

参考文档:
总结
田忌赛马,贪心算法,逐步扩大优势.以局部的优势,和战略性的放弃,达到整体的最优解


160

被折叠的 条评论
为什么被折叠?



