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

92 阅读3分钟

解题思路

问题理解

小R正在组织一个比赛,比赛中有 n 支队伍参赛。比赛遵循以下独特的赛制:

  • 如果当前队伍数为 偶数,那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛,且产生 n / 2 支队伍进入下一轮。
  • 如果当前队伍数为 奇数,那么将会随机轮空并晋级一支队伍,其余的队伍配对。总共进行 (n - 1) / 2 场比赛,且产生 (n - 1) / 2 + 1 支队伍进入下一轮。

小R想知道在比赛中进行的配对次数,直到决出唯一的获胜队伍为止。

数据结构选择

在这个问题中,我们不需要复杂的数据结构。我们只需要一个整数变量来记录当前的队伍数 n,以及另一个整数变量来记录配对次数 pairs

算法步骤

  1. 初始化

    • 初始化 pairs 为 0,表示初始配对次数为 0。
    • 初始化 n 为输入的队伍数。
  2. 循环处理每一轮比赛

    • 当 n 大于 1 时,继续进行比赛。

    • 如果 n 为偶数:

      • 配对次数 pairs 增加 n / 2
      • 更新 n 为 n / 2
    • 如果 n 为奇数:

      • 配对次数 pairs 增加 (n - 1) / 2
      • 更新 n 为 (n - 1) / 2 + 1
  3. 返回结果

    • 当 n 变为 1 时,循环结束,返回 pairs 作为最终的配对次数。

详细步骤

  1. 初始化

    • pairs = 0
    • n = 输入的队伍数
  2. 循环处理每一轮比赛

    • 循环条件while n > 1

      • 偶数情况

        • 如果 n % 2 == 0

          • pairs += n // 2
          • n = n // 2
      • 奇数情况

        • 如果 n % 2 != 0

          • pairs += (n - 1) // 2
          • n = (n - 1) // 2 + 1
  3. 返回结果

    • return pairs

总结

算法复杂度分析

  • 时间复杂度

    • 每次循环中,队伍数 n 至少减半(偶数情况)或接近减半(奇数情况)。因此,循环的次数大约为 log(n) 次。
    • 每次循环中的操作是常数时间复杂度 O(1)
    • 因此,总的时间复杂度为 O(log(n))
  • 空间复杂度

    • 只使用了两个整数变量 pairs 和 n,因此空间复杂度为 O(1)

代码实现

def solution(n: int) -> int:

    # 初始化配对次数

    pairs = 0

    

    # 循环直到队伍数变为1

    while n > 1:

        if n % 2 == 0:

            # 队伍数为偶数

            pairs += n // 2  # 增加 n / 2 次配对

            n = n // 2  # 更新队伍数

        else:

            # 队伍数为奇数

            pairs += (n - 1) // 2  # 增加 (n - 

            1) / 2 次配对

            n = (n - 1) // 2 + 1  # 更新队伍数

    

    return pairs

if name == 'main':

    print(solution(7) == 6)

    print(solution(14) == 13)

    print(solution(1) == 0)

代码解释

  • 初始化pairs = 0 和 n = 输入的队伍数
  • 循环while n > 1,根据 n 的奇偶性更新 pairs 和 n
  • 返回return pairs,返回最终的配对次数。

测试样例

  • 样例1n = 7

    • 初始 pairs = 0n = 7
    • 第一轮:pairs += (7 - 1) // 2 = 3n = (7 - 1) // 2 + 1 = 4
    • 第二轮:pairs += 4 // 2 = 2n = 4 // 2 = 2
    • 第三轮:pairs += 2 // 2 = 1n = 2 // 2 = 1
    • 最终 pairs = 6
  • 样例2n = 14

    • 初始 pairs = 0n = 14
    • 第一轮:pairs += 14 // 2 = 7n = 14 // 2 = 7
    • 第二轮:pairs += (7 - 1) // 2 = 3n = (7 - 1) // 2 + 1 = 4
    • 第三轮:pairs += 4 // 2 = 2n = 4 // 2 = 2
    • 第四轮:pairs += 2 // 2 = 1n = 2 // 2 = 1
    • 最终 pairs = 13
  • 样例3n = 1

    • 初始 pairs = 0n = 1
    • 直接返回 pairs = 0

总结

通过上述分析和代码实现,我们可以看到,这个问题可以通过简单的循环和条件判断来解决。关键在于理解每轮比赛的规则,并正确更新队伍数和配对次数。时间复杂度为 O(log(n)),空间复杂度为 O(1),是一个高效且简洁的解决方案。