问题描述
小 M 和小 F 正在进行一场 n 轮随机英雄决斗比赛。 在每一轮中,小 M 和小 F 各自从他们的英雄队伍中选出一位英雄进行对决,英雄的能力值将决定胜负:
• 能力值高的一方获胜。
• 能力值相同时,小M视为失败。
小 M 已经按照固定的顺序选择英雄(即其能力值固定为 1, 2, 3, \dots, n),而小 F 可以自由调整其英雄的出场顺序。
任务: 请帮助小 F 确定一个最佳的出场顺序,以获得最多的胜利场次。
输入说明
• number:一个整数,表示比赛的总轮数 n。
• heroes:一个长度为 n 的正整数数组,表示小F每个英雄的能力值。
输出
返回一个整数,表示小 F 可以获得的最大胜利场次。
解题思路
为了获得最多胜利,小 F 需要策略性地安排英雄的出场顺序,重点在于:
• 优先用能力值大于小M的英雄匹配其最弱的英雄(即小M的能力值最小的那位)。
• 用能力值较小的英雄消耗小M较强的英雄。
实现过程中,可以使用 双指针法 来实现这一策略:
1. 排序英雄能力值:
• 小M的英雄队伍固定为 [1, 2, 3, ..., n]。
• 小F的英雄队伍按能力值升序排列,以便从小到大灵活匹配。
2. 双指针匹配规则:
• 用两个指针分别指向小M队伍和小F队伍的当前英雄。
• 如果小F当前英雄的能力值能战胜小M当前英雄(即 heroes[f_index] > u_heros[u_index]),则视为获胜:
• 小M和小F的指针分别移动到下一个英雄。
• 否则(即无法战胜小M当前英雄),小F用最弱的英雄与之消耗:
• 小F的指针移动到下一个英雄。
3. 计数胜利场次:
• 每次小F获胜时,将胜利次数 victories 加 1。
代码实现
运行分析
1. 时间复杂度:
• 排序复杂度为 O(n \log n)。
• 双指针遍历队伍复杂度为 O(n)。
• 总时间复杂度:O(n \log n)。
2. 空间复杂度:
• 使用了几个整数变量,空间复杂度为 O(1)。
• 总空间复杂度:O(1)。
测试分析
测试用例 1 输入:number = 7, heroes = [10, 1, 1, 1, 5, 5, 3] 输出:4 解释:
• 小M队伍:[1, 2, 3, 4, 5, 6, 7]。
• 小F排序后队伍:[1, 1, 1, 3, 5, 5, 10]。
• 按策略出场:
1. 用 3 打败小M的 1。
2. 用 5 打败小M的 2。
3. 用 5 打败小M的 3。
4. 用 10 打败小M的 4。
• 最终获胜场次为 4。
测试用例 2 输入:number = 5, heroes = [1, 1, 1, 1, 1] 输出:0 解释: 小 F 无论如何调整出场顺序,都无法战胜小 M 的任何英雄。
测试用例 3 输入:number = 6, heroes = [9, 4, 7, 3, 2, 6] 输出:6 解释: 小 F 排序后队伍为 [2, 3, 4, 6, 7, 9],可以完全战胜小 M 队伍 [1, 2, 3, 4, 5, 6]。
扩展总结
• 解题关键:排序与双指针。
• 思考点:如何在匹配中最大化小F的胜利场次。
这种问题类似于“分配问题”,可以扩展到多种场景,如最优资源分配等。 在实际算法比赛中,双指针是一种高效处理排序后数据的经典工具。