返回

深入理解阶乘后的零:超越投机取巧的算法题

见解分享

作为一名技术博主,我总是着迷于破解算法难题背后的奥秘。最近,我钻研了LeetCode上的第172号问题:阶乘后的零,一道被标记为“简单”但实际却充满挑战性的题目。在本文中,我将超越表面上的投机取巧,深入探讨这道题目的本质,提供清晰、全面的解释。

理解问题本质

第172号问题要求我们计算一个整数 n 的阶乘 n! 中尾随零的数量。例如,5! = 120,尾随零的数量为 1;25! = 15511210043330985984000000,尾随零的数量为 6。

投机取巧的解法

一种常见的投机取巧解法是根据以下观察:

  • 10 的倍数: 任何包含 10 作为因子的数字都会产生尾随零。
  • 5 的倍数: 产生尾随零的唯一方法是包含 10 的因子。而 10 的因子又包含 2 和 5 的因子。

因此,我们可以计算 n 中 5 的因子的个数,这将给出尾随零的数量。

优化算法

虽然投机取巧的解法可以解决问题,但它在某些情况下可能效率低下。例如,当 n 非常大时,计算 5 的因子的个数会变得非常耗时。一种更优化的算法是基于以下观察:

  • 2 的因子数量: 尾随零的数量是由 2 的因子的数量决定的,因为每个 10 的因子都包含一个 2 和一个 5 的因子。
  • 5 的因子数量: 5 的因子数量永远不会多于 2 的因子数量,因为每个 5 的因子都必须包含一个 2 的因子。

因此,我们可以只计算 2 的因子的数量,并将其作为尾随零的数量。

分步实现

以下是如何分步实现优化的算法:

  1. 初始化变量 zeros 为 0,它将存储尾随零的数量。
  2. 循环变量 n,从 2 到 n
  3. 对于每个 i,将 n 除以 i 并将结果存储在变量 quotient 中。
  4. quotient 加到 zeros 中,这表示 in 的因子。
  5. 由于 5 的因子数量永远不会多于 2 的因子数量,因此我们可以提前终止循环。

完整代码

以下是算法的完整代码:

def trailing_zeros(n):
  """
  计算 n! 尾随零的数量。

  参数:
    n: 输入整数。

  返回:
    尾随零的数量。
  """

  zeros = 0
  for i in range(2, n + 1):
    quotient = n // i
    zeros += quotient

  return zeros

结论

通过深入理解问题本质和优化算法,我们能够超越投机取巧的解法,以更有效的方式解决阶乘后的零问题。这道算法题不只是一次练习,它还教会了我们如何分解复杂问题,找到更有效的解决方案,并在代码实现中体现我们的发现。

我希望这篇博文不仅能帮助你解决这个问题,还能激励你对算法和数学概念进行更深入的探索。如果你有任何问题或意见,欢迎在下方评论区留言。