题目解析:英雄决斗的最大胜利次数| 豆包MarsCode AI刷题

60 阅读3分钟

问题描述

小 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

代码实现

截屏2024-11-26 14.12.04.png

运行分析

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的胜利场次。

这种问题类似于“分配问题”,可以扩展到多种场景,如最优资源分配等。 在实际算法比赛中,双指针是一种高效处理排序后数据的经典工具。