【LeetCode 172】阶乘后的零(C语言详解 | 数学规律 + 对数时间复杂度)

一、题目描述

给定一个整数 n ,返回 n! 结果中 尾随零的数量

阶乘定义:

复制代码
n! = n × (n-1) × (n-2) × ... × 3 × 2 × 1

示例

示例 1

复制代码
输入:n = 3
输出:0
解释:3! = 6,没有尾随 0

示例 2

复制代码
输入:n = 5
输出:1
解释:5! = 120,有 1 个尾随 0

示例 3

复制代码
输入:n = 0
输出:0

数据范围

复制代码
0 <= n <= 10^4

进阶要求:设计 O(log n) 时间复杂度的算法。


二、问题关键

尾随 0 的来源是 10

而:

复制代码
10 = 2 × 5

也就是说:

复制代码
只要有一对 (2,5) 就会产生一个 0

例如:

复制代码
2 × 5 = 10 → 产生一个 0

三、为什么只需要统计 5?

n! 中:

  • 偶数很多 → 2 的因子很多

  • 5 的因子比较少

例如:

复制代码
10! = 3628800

里面:

复制代码
2 的数量 >> 5 的数量

因此:

复制代码
尾随 0 的数量 = 5 的因子数量

四、需要注意的特殊情况

某些数提供 多个 5

例如:

复制代码
25 = 5 × 5
125 = 5 × 5 × 5

所以计算公式为:

复制代码
n/5 + n/25 + n/125 + ...

直到为 0。


五、图解理解

n = 25 为例:

第一次统计

复制代码
25 / 5 = 5

说明:

复制代码
5,10,15,20,25

5 个 5


第二次统计

复制代码
25 / 25 = 1

说明:

复制代码
25 = 5 × 5

多贡献 1 个 5


总数

复制代码
5 + 1 = 6

因此:

复制代码
25! 尾随 0 = 6

六、解法一:数学规律(推荐)

核心思路:

不断除以 5。

复制代码
n/5
n/25
n/125
...

时间复杂度:

复制代码
O(log₅ n)

C语言实现

复制代码
int trailingZeroes(int n) {
    int count = 0;

    while (n > 0) {
        n /= 5;
        count += n;
    }

    return count;
}

七、解法二:for循环写法

逻辑完全相同,只是写法不同。

C语言实现

复制代码
int trailingZeroes(int n) {
    int count = 0;

    for (long long i = 5; i <= n; i *= 5) {
        count += n / i;
    }

    return count;
}

过程示例(n=100)

复制代码
100/5  = 20
100/25 = 4
100/125 = 0

结果:

复制代码
20 + 4 = 24

八、错误解法(不推荐)

有些人会真的去计算:

复制代码
n!

例如:

复制代码
5! = 120
10! = 3628800

然后统计末尾 0。

这种方法问题:

1️⃣ 阶乘非常大

复制代码
20! 就已经超过 long long

2️⃣ 时间复杂度高

因此不推荐。


九、复杂度分析

方法 时间复杂度 空间复杂度
数学统计 O(log n) O(1)
暴力阶乘 极高 极高

十、总结

核心思想只有一句话:

复制代码
阶乘尾零 = 统计所有因子5的数量

计算公式:

复制代码
n/5 + n/25 + n/125 + ...

最终实现只需 几行代码 ,时间复杂度 O(log n)

相关推荐
自信150413057591 小时前
数据结构初阶——二叉树之——堆的实现
c语言·数据结构·算法
Barkamin1 小时前
(有头)链表的实现(Java)
java·数据结构·链表
!停2 小时前
数据结构算法—归并排序
数据结构·算法
骇客野人2 小时前
机器学习线性回归算法是入门机器学习理解人工智能模型很好示例
人工智能·算法·机器学习
Trouvaille ~2 小时前
【贪心算法】专题(三):排序、博弈与区间的贪婪法则
c++·算法·leetcode·青少年编程·面试·贪心算法·蓝桥杯
Sakinol#2 小时前
Leetcode Hot 100 —— 二叉树 part02
算法·leetcode
N1_WEB2 小时前
HDU:杭电 2017 复试真题汇总
算法
努力学算法的蒟蒻2 小时前
day111(3.13)——leetcode面试经典150
算法·leetcode·面试
参.商.2 小时前
【Day37】94.二叉树的中序遍历 递归+迭代遍历
leetcode·golang