题目说明(python作答)
小U和小F正在进行一场由 nn 轮组成的英雄决斗比赛。在每一轮中,小U和小F各自从他们的英雄队伍中选出一位英雄进行对决,英雄的能力值将决定比赛的胜负,能力值高者获胜。小U已经按照固定的能力顺序 1,2,3,…,n1,2,3,…,n 安排了他的英雄出场顺序。
小F希望通过调整他的英雄出场顺序,最大化他的获胜轮数。请帮助小 F 确定一个最佳的出场顺序,以获得最多的胜利。
输入说明
number: 一个整数,表示比赛的总轮数 nn。heroes: 一个长度为 nn 的正整数数组,表示小 F 的每个英雄的能力值。
输出
- 返回一个整数,表示小 F 可以获得的最大胜利轮数
# 题目解析
这个题目是中等难度,不过所需要的知识和算法的比较简单。 通过题目描述我们可以知道小f是一个打乱的数组,同样,小U在题目中也提示我们它是一个数组,元素是1-n,题目让我们确定一个小F最佳的出场顺序的内容是一个无关紧要的条件,因为最后我们是返回小F的胜利的最大轮数。最开始看到这道题的时候,我想过用二分查找,并且结合豆包的代码提示:
def solution(number, heroes):
# 对小F的英雄能力值进行排序
heroes.sort()
# 初始化胜利次数
wins = 0
# 从小到大遍历小U的英雄能力值
for u_hero in range(1, number + 1):
# 使用二分查找找到最小的且大于等于u_hero的英雄
left, right = 0, len(heroes) - 1
while left <= right:
mid = (left + right) // 2
if heroes[mid] >= u_hero:
right = mid - 1
else:
left = mid + 1
# 如果找到,胜利次数加1,并从heroes中移除该英雄
if left < len(heroes):
wins += 1
heroes.pop(left)
return wins
结果运行错误,欸奇了怪了,我又重新开始审视题目,两个半小时,我看出一些端倪,小U是一个从小到大的数组,并且小U和小F的比较每个英雄都只有一次机会,让小F数组也由小到大排序,然后一个一个比较,那么结果就是最大的胜利轮数:这是1v1的游戏,你派出最弱的,我能派出最强的吗?打完就上不了了呀,我肯定也拿最弱的,赢了我就赚了,输了也没关系,还有下一回合,我就先派出弱的,反正你也是按照弱到高排序吧,前期连胜那我就是good,前期连败我就吃利息,还是赚,好了,不废话了哈哈,上代码:
def solution(number, heroes):
# 对小F的英雄能力值进行排序
heroes.sort()
u_heroes = list(range(1, number + 1))
u_pointer, f_pointer = 0, 0
wins = 0
while f_pointer < number and u_pointer < number:
if heroes[f_pointer] > u_heroes[u_pointer]:
wins += 1
u_pointer += 1
f_pointer += 1
return wins
思路就是一个个进行比较,赢了我就加1,输了咱们就继续比较下一个,这个方法能保证win是最大次数的无论小F给什么,有多少个英雄比小U大,我们就会胜利多少次,当然我也给了for类的遍历,不过时间复杂度较高,本人实力有限,也不知道怎么优化了。如下,各位看官查收:
def solution(number, heroes):
# 对小F的英雄能力值进行排序
heroes.sort()
u_heroes = list(range(1, number + 1))
u_pointer, f_pointer = 0, 0
wins = 0
for f_pointer in range(number):
for u_pointer in range(number):
if heroes[f_pointer] > u_heroes[u_pointer]:
# F's hero can win this round
wins += 1
u_pointer += 1
break
f_pointer += 1
return wins
第一次发文,考虑到我们许多同学可能刚接触算法,就只用了能看的懂的线性查找,各位看官有什么问题可以一起交流哦,我陈平安很荣幸能和大家一起讨论