今天刷的是一道难度中等的题目:英雄决斗的最大胜利次数
问题描述
小U和小F正在进行一场由 n 轮组成的英雄决斗比赛。在每一轮中,小U和小F各自从他们的英雄队伍中选出一位英雄进行对决,英雄的能力值将决定比赛的胜负,能力值高者获胜。小U已经按照固定的能力顺序 1,2,3,…,n 安排了他的英雄出场顺序。
小F希望通过调整他的英雄出场顺序,最大化他的获胜轮数。请帮助小 F 确定一个最佳的出场顺序,以获得最多的胜利。
输入说明
number: 一个整数,表示比赛的总轮数 nn。heroes: 一个长度为 nn 的正整数数组,表示小 F 的每个英雄的能力值。
输出
- 返回一个整数,表示小 F 可以获得的最大胜利轮数。
测试样例
样例1:
输入:
number = 7, heroes = [10, 1, 1, 1, 5, 5, 3]
输出:4
样例2:
输入:
number = 5, heroes = [1, 1, 1, 1, 1]
输出:0
样例3:
输入:
number = 6, heroes = [9, 4, 7, 3, 2, 6]
输出:6
一开始我没有特别好的思路,于是尝试问了豆包的AI,开始有了一些思路如下:
算法设计详细步骤
-
输入处理:
- 读取输入数据,包括比赛轮数
number和小F的英雄能力值数组heroes。
- 读取输入数据,包括比赛轮数
-
英雄排序:
- 使用快速排序或归并排序对小F的英雄能力值进行排序。排序后的数组使得在进行胜利比较时,可以更高效地找到能够击败小U的英雄。
-
轮次比较:
-
初始化胜利计数器
wins为0,和一个指针j用于遍历小F的英雄数组。 -
遍历小U的英雄能力值(从1到n):
-
对于每一个小U的英雄能力值
i:- 当
j小于小F英雄数量且小F的英雄能力值heroes[j]小于等于i时,说明小F的当前英雄无法击败小U的这个英雄,继续移动指针j。 - 一旦找到一个小F的英雄能力值
heroes[j]大于i,就说明小F赢得了这一轮,计数器wins加1,然后将指针j向前移动一位,继续比较下一个小U的英雄。
- 当
-
-
-
输出结果:
- 最后输出胜利计数器
wins的值,即小F获胜的轮数。
- 最后输出胜利计数器
复杂度分析
时间复杂度
-
排序:
- 排序的时间复杂度为 O(n log n),这是因为使用了高效的排序算法(如快速排序或归并排序)。
-
比较:
- 轮次比较是线性的。对于小U的每个英雄(n轮),在最坏情况下我们可能需要遍历小F的所有英雄,因此每轮比较最多需要 O(n) 的时间。
- 由于小F的英雄最多也只需被遍历一次,总体比较过程时间复杂度为 O(n)。
-
整体复杂度:
- 由于排序是最主导的因素,整体时间复杂度为 O(n log n)。
空间复杂度
-
存储:
- 在排序过程中,如果使用的排序算法需要额外的存储空间(如归并排序的辅助数组),那么空间复杂度为 O(n)。如果使用的排序算法是原地排序(如快速排序),则空间复杂度为 O(1)。
-
其他变量:
- 需要少量额外的变量(如计数器和指针),这些都是 O(1) 的空间。
-
总体空间复杂度:
- 如果考虑排序使用的辅助空间,整体空间复杂度为 O(n)。如果是原地排序,空间复杂度则为 O(1)。
总结
- 本算法通过排序小F的英雄能力值和使用双指针方法进行轮次比较,达到高效的胜利计数。时间复杂度为 O(n log n),空间复杂度在最坏情况下为 O(n)。这个贪心策略非常适合这个问题,因为它利用了英雄能力值的顺序性来最大化小F的胜利次数。
最后成功ac了这道题目,我觉得豆包的AI功能还是特别好的,希望明天可以继续加油!!