【Leetcode】2410. 运动员和训练师的最大匹配数
文章目录
- 题目描述
- 示例
- 解题思路
- 算法步骤
- 代码实现
- C++实现
- Java实现
- Python实现
- 算法分析
- 正确性证明
- 复杂度分析
- 关键点总结
题目描述
题目链接🔗
给你一个下标从 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) - 1idx2 = len(trainers) - 1ans = 0while idx1 >= 0 and idx2 >= 0:if players[idx1] <= trainers[idx2]:idx1 -= 1idx2 -= 1ans += 1else:idx1 -= 1return ans
算法分析
正确性证明
贪心策略的正确性:
- 对于能力最强的运动员,如果有训练师能够匹配,我们应该选择能力最强的训练师
- 这样可以为其他运动员保留更多的匹配机会
- 如果最强的训练师都无法匹配最强的运动员,那么其他训练师也无法匹配
算法流程:
- 从最强的运动员开始
- 如果当前最强的训练师可以匹配,则匹配
- 否则该运动员无法被任何训练师匹配,跳过
- 重复直到所有运动员或训练师都被处理
复杂度分析
- 时间复杂度:O(n log n + m log m),其中 n 是运动员数量,m 是训练师数量
- 排序:O(n log n + m log m)
- 双指针遍历:O(n + m)
- 空间复杂度:O(1),只使用了常数级额外空间
关键点总结
- 贪心思想:让强者配强者,避免资源浪费
- 排序预处理:为贪心策略提供基础
- 双指针技巧:高效地进行匹配判断
- 从大到小:确保贪心策略的正确性
这个算法通过贪心策略和双指针技巧,以最优的方式解决了运动员与训练师的匹配问题,是贪心算法的经典应用。