青训营X豆包MarsCode技术训练营第一课|豆包MarsCode刷题

118 阅读4分钟

今天刷的是一道难度中等的题目:英雄决斗的最大胜利次数

问题描述

小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,开始有了一些思路如下:

算法设计详细步骤

  1. 输入处理

    • 读取输入数据,包括比赛轮数 number 和小F的英雄能力值数组 heroes
  2. 英雄排序

    • 使用快速排序或归并排序对小F的英雄能力值进行排序。排序后的数组使得在进行胜利比较时,可以更高效地找到能够击败小U的英雄。
  3. 轮次比较

    • 初始化胜利计数器 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的英雄。
  4. 输出结果

    • 最后输出胜利计数器 wins 的值,即小F获胜的轮数。

复杂度分析

时间复杂度

  1. 排序

    • 排序的时间复杂度为 O(n log n),这是因为使用了高效的排序算法(如快速排序或归并排序)。
  2. 比较

    • 轮次比较是线性的。对于小U的每个英雄(n轮),在最坏情况下我们可能需要遍历小F的所有英雄,因此每轮比较最多需要 O(n) 的时间。
    • 由于小F的英雄最多也只需被遍历一次,总体比较过程时间复杂度为 O(n)。
  3. 整体复杂度

    • 由于排序是最主导的因素,整体时间复杂度为 O(n log n)。

空间复杂度

  1. 存储

    • 在排序过程中,如果使用的排序算法需要额外的存储空间(如归并排序的辅助数组),那么空间复杂度为 O(n)。如果使用的排序算法是原地排序(如快速排序),则空间复杂度为 O(1)。
  2. 其他变量

    • 需要少量额外的变量(如计数器和指针),这些都是 O(1) 的空间。
  3. 总体空间复杂度

    • 如果考虑排序使用的辅助空间,整体空间复杂度为 O(n)。如果是原地排序,空间复杂度则为 O(1)。

总结

  • 本算法通过排序小F的英雄能力值和使用双指针方法进行轮次比较,达到高效的胜利计数。时间复杂度为 O(n log n),空间复杂度在最坏情况下为 O(n)。这个贪心策略非常适合这个问题,因为它利用了英雄能力值的顺序性来最大化小F的胜利次数。

最后成功ac了这道题目,我觉得豆包的AI功能还是特别好的,希望明天可以继续加油!!