目录
力扣870. 优势洗牌(田忌赛马)
解析代码
力扣870. 优势洗牌(田忌赛马)
870. 优势洗牌
难度 中等
给定两个长度相等的数组 nums1
和 nums2
,nums1
相对于 nums2
的优势可以用满足 nums1[i] > nums2[i]
的索引 i
的数目来描述。
返回 nums1 的任意排列,使其相对于 nums2
的优势最大化。
示例 1:
输入:nums1 = [2,7,11,15], nums2 = [1,10,4,11] 输出:[2,11,7,15]
示例 2:
输入:nums1 = [12,24,8,32], nums2 = [13,25,32,11] 输出:[24,32,8,12]
提示:
1 <= nums1.length <= 10^5
nums2.length == nums1.length
0 <= nums1[i], nums2[i] <= 10^9
class Solution {
public:
vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
}
};
解析代码
这里讲一下田忌赛马背后的博弈决策,从三匹马拓展到 n 匹马之间博弈的最优策略。
- 田忌:下等马 中等马 上等马
- 齐王:下等马 中等马 上等马
- 田忌的下等马 pk 不过齐王的下等马,因此把这匹马丢去消耗一个齐王的最强的马。
- 接下来选择中等马 pk 齐王的下等马,勉强获胜。
- 最后用上等马 pk 齐王的中等马,勉强获胜。
由此可以得出一个最优的决策方式:
- 当我方此时最差的比不过对面最差的时候,让我方最差的去处理掉对面最好的(反正要输,不如去拖掉对面一个最强的)。
- 当我方此时最差的能比得上对面最差的时候,就让两者比对下去(最差的都能获胜,就不需要更强的比了)。
class Solution {
public:
vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
int sz = nums1.size();
sort(nums1.begin(), nums1.end());
vector<int> index(sz), ret(sz); // index和nums2下标绑定
for(int i = 0; i < sz; ++i)
{
index[i] = i;
}
sort(index.begin(), index.end(),[&](int index1, int index2)
{
return nums2[index1] < nums2[index2];
});
int left = 0, right = sz - 1;
for(auto& e : nums1)
{
if(e <= nums2[index[left]]) // 最弱的和最弱的判断
ret[index[right--]] = e; // 比不过就去和最强的比,相等也比不过
else // 比过了,放到最弱的位置
ret[index[left++]] = e;
}
return ret;
}
};