豆包MarsCode 刷题(九) | 豆包MarsCode AI刷题

63 阅读3分钟

本博客含有一道题目:英雄决斗的最大胜利次数

英雄决斗的最大胜利次数

问题描述

小U和小F正在进行一场由 n 轮组成的英雄决斗比赛。在每一轮中,小U和小F各自从他们的英雄队伍中选出一位英雄进行对决,英雄的能力值将决定比赛的胜负,能力值高者获胜。小U已经按照固定的能力顺序 1,2,3,…,n安排了他的英雄出场顺序。

小F希望通过调整他的英雄出场顺序,最大化他的获胜轮数。请帮助小 F 确定一个最佳的出场顺序,以获得最多的胜利。

输入说明

  • number: 一个整数,表示比赛的总轮数 n
  • heroes: 一个长度为 n的正整数数组,表示小 F 的每个英雄的能力值。

输出

  • 返回一个整数,表示小 F 可以获得的最大胜利轮数。

问题理解

小U的英雄出场顺序是固定的,能力值为 1, 2, 3, ..., n。小F需要通过调整他的英雄出场顺序,最大化他的获胜轮数。

我的思路

  • 对输入的 heros 数组进行从小到大的排序

  • 遍历排序后的数组,小U遍历序号为 i ,小F序号为 j

    • 如果该位置的战力大(即U[i] > F[j] ),则小U和小F的序号加一,并且胜利次数加一
    • 如果该位置的战力不大大(即U[i] <= F[j] ),则小F的序号加一
  • 遍历完成之后返回胜场次数。

数据结构选择

  • 小U的英雄能力值是固定的,可以直接使用一个数组 [1, 2, 3, ..., n] 来表示。
  • 小F的英雄能力值是一个数组 heroes,我们需要对这个数组进行排序,以便找到最佳的出场顺序。

豆包思路

  1. 排序:首先对小F的英雄能力值数组 heroes 进行排序。
  2. 双指针法:使用两个指针,一个指向小U的英雄能力值数组(从1到n),另一个指向排序后的小F的英雄能力值数组。
  3. 匹配:通过比较两个指针指向的值,如果小F的英雄能力值大于小U的英雄能力值,则小F获胜,两个指针都向前移动;否则,只移动小F的指针,继续寻找下一个可能获胜的英雄。
  4. 计数:统计小F获胜的轮数。

思路融合并编程

对比思路之后,发现我的思路与豆包思路几乎一致,但是豆包思路比我的表述更为清晰。

def solution(number, heroes):
    # 1. 对小F的英雄能力值数组进行排序
    heroes.sort()
    
    # 2. 初始化小U的英雄能力值数组
    u_heroes = list(range(1, number + 1))
    
    # 3. 初始化双指针
    u_pointer = 0
    f_pointer = 0
    
    # 4. 初始化胜利轮数计数器
    win_count = 0
    
    # 5. 使用双指针法进行匹配
    while u_pointer < number and f_pointer < number:
        # 如果小F的英雄能力值大于小U的英雄能力值
        if heroes[f_pointer] > u_heroes[u_pointer]:
            # 小F获胜,两个指针都向前移动
            win_count += 1
            u_pointer += 1
        # 无论是否获胜,小F的指针都要向前移动
        f_pointer += 1
    
    # 6. 返回小F的最大胜利轮数
    return win_count
​

总结

通过排序和双指针法,我们可以有效地找到小F的最佳出场顺序,从而最大化他的获胜轮数。