题目描述
题目链接🔗
给你一个下标从 0 开始的整数数组 players ,其中 players[i] 是第 i 名运动员的能力。同样给你一个下标从 0 开始的整数数组 trainers ,其中 trainers[j] 是第 j 名训练师的训练能力。
如果第 i 名运动员的能力 小于等于 第 j 名训练师的训练能力,那么第 i 名运动员可以 匹配 第 j 名训练师。
返回满足上述条件 且能够匹配 的 最大 运动员数目。
示例
示例 1:
输入:players = [4,7,9], trainers = [8,2,5,8]
输出:2
解释:
我们可以将运动员按如下方式匹配:
- 运动员 0 可以匹配训练师 0 ,因为 4 <= 8 。
- 运动员 1 可以匹配训练师 3 ,因为 7 <= 8 。
可以证明 2 是可以匹配的最大运动员数目。
示例 2:
输入:players = [1,1,1], trainers = [10]
输出:1
解释:
训练师可以被所有 3 个运动员匹配。
每个训练师最多可以匹配一个运动员,所以最多答案是 1 。
解题思路
这是一个典型的贪心算法问题。为了最大化匹配数量,我们应该:
- 贪心策略:让能力强的运动员匹配能力强的训练师,能力弱的运动员匹配能力弱的训练师
- 从大到小匹配:先处理能力最强的运动员和训练师,这样可以避免强训练师被弱运动员"浪费"
算法步骤
- 排序:对运动员数组和训练师数组进行升序排序
- 双指针:从两个数组的最大值开始,使用双指针进行匹配
- 匹配判断:
- 如果
players[i] <= trainers[j],则可以匹配,两个指针都向前移动 - 如果
players[i] > trainers[j],则当前训练师无法匹配该运动员,只移动运动员指针
- 如果
- 返回结果:返回成功匹配的运动员数量
代码实现
C++实现
class Solution {
public:
int matchPlayersAndTrainers(vector<int>& players, vector<int>& trainers) {
// 对两个数组进行排序
sort(players.begin(), players.end());
sort(trainers.begin(), trainers.end());
// 双指针从最大值开始
int idx1 = players.size() - 1; // 运动员指针
int idx2 = trainers.size() - 1; // 训练师指针
int ans = 0;
// 双指针匹配
while (idx1 >= 0 && idx2 >= 0) {
if (players[idx1] <= trainers[idx2]) {
// 可以匹配,两个指针都向前移动
idx1--;
idx2--;
ans++;
} else {
// 当前训练师无法匹配该运动员,只移动运动员指针
idx1--;
}
}
return ans;
}
};
Java实现
class Solution {
public int matchPlayersAndTrainers(int[] players, int[] trainers) {
Arrays.sort(players);
Arrays.sort(trainers);
int idx1 = players.length - 1;
int idx2 = trainers.length - 1;
int ans = 0;
while (idx1 >= 0 && idx2 >= 0) {
if (players[idx1] <= trainers[idx2]) {
idx1--;
idx2--;
ans++;
} else {
idx1--;
}
}
return ans;
}
}
Python实现
class Solution:
def matchPlayersAndTrainers(self, players: List[int], trainers: List[int]) -> int:
players.sort()
trainers.sort()
idx1 = len(players) - 1
idx2 = len(trainers) - 1
ans = 0
while idx1 >= 0 and idx2 >= 0:
if players[idx1] <= trainers[idx2]:
idx1 -= 1
idx2 -= 1
ans += 1
else:
idx1 -= 1
return ans
算法分析
正确性证明
贪心策略的正确性:
- 对于能力最强的运动员,如果有训练师能够匹配,我们应该选择能力最强的训练师
- 这样可以为其他运动员保留更多的匹配机会
- 如果最强的训练师都无法匹配最强的运动员,那么其他训练师也无法匹配
算法流程:
- 从最强的运动员开始
- 如果当前最强的训练师可以匹配,则匹配
- 否则该运动员无法被任何训练师匹配,跳过
- 重复直到所有运动员或训练师都被处理
复杂度分析
- 时间复杂度:O(n log n + m log m),其中 n 是运动员数量,m 是训练师数量
- 排序:O(n log n + m log m)
- 双指针遍历:O(n + m)
- 空间复杂度:O(1),只使用了常数级额外空间
关键点总结
- 贪心思想:让强者配强者,避免资源浪费
- 排序预处理:为贪心策略提供基础
- 双指针技巧:高效地进行匹配判断
- 从大到小:确保贪心策略的正确性
这个算法通过贪心策略和双指针技巧,以最优的方式解决了运动员与训练师的匹配问题,是贪心算法的经典应用。
371

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



