Factorial Trailing Zeroes

本文介绍了一种高效算法来计算给定整数n的阶乘末尾零的数量。通过分析阶乘中5的倍数及其幂次出现的频率,提出了一种对数时间复杂度的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given an integer n, return the number of trailing zeroes in n!.

Note: Your solution should be in logarithmic time complexity.



思路:如果要知道多少个0,就需要找到他们的约数中,有多少个2和5,由于2的个数必多于5,所以,找到5的个数即可

思路1:最笨的方法,暴力O(n),从2遍历到n,找到每个数中5的个数,累计求和

思路2:参考网上思路,给定一个数n,从1至n,仅含有一个5的数的个数为n/5,含有2个5的个数为n/25,因此,每次除以5的个数累计求和即可

代码:
class Solution {
public:
    int trailingZeroes(int n) {
        int res = 0;
        while(n){
            res += n/5;
            n /= 5;
        }
        return res;
    }
};
### 计算双阶乘结果中末尾零的数量 #### 问题分析 要计算双阶乘 \( f(n) = n \cdot f(n-2) \) 的结果中十进制表示的末尾零数量,可以将其转化为统计因子中的质因数分解情况。具体来说,在十进制下,一个数字末尾有零意味着该数字能被 \( 10 \) 整除,而 \( 10 = 2 \times 5 \)。因此,我们需要统计双阶乘展开式中因子 \( 2 \) 和 \( 5 \) 出现的次数。 由于通常情况下因子 \( 2 \) 的数量远多于因子 \( 5 \),所以只需关注因子 \( 5 \) 的数量即可得出末尾零的数量[^1]。 --- #### 解决方法 对于给定的正整数 \( n \),我们可以通过以下方式来计算其双阶乘结果中末尾零的数量: 1. **定义双阶乘** 双阶乘分为两种形式: - 当 \( n \) 是偶数时:\( f(n) = n \cdot (n-2) \cdot (n-4) \cdots 2 \) - 当 \( n \) 是奇数时:\( f(n) = n \cdot (n-2) \cdot (n-4) \cdots 1 \) 2. **提取因子 \( 5 \)** 我们只需要遍历双阶乘序列中的每一个数,并统计其中能够贡献因子 \( 5 \) 的部分。假设当前数为 \( k \),则它所含有的因子 \( 5 \) 数量可以用如下公式计算: \[ g(k) = \left\lfloor \frac{k}{5} \right\rfloor + \left\lfloor \frac{k}{5^2} \right\rfloor + \left\lfloor \frac{k}{5^3} \right\rfloor + \cdots \] 3. **实现算法** 下面给出 Python 实现代码: ```python def count_trailing_zeros_double_factorial(n): def count_factors_of_5(x): # 统计单个数 x 中含有多少个因子 5 cnt = 0 while x >= 5: x //= 5 cnt += x return cnt if n < 0: # 如果输入小于 0,则返回 0 return 0 total_count = 0 step = 2 if n % 2 == 0 else 1 # 偶数步长为 2;奇数步长为 1 for i in range(n, 0, -step): total_count += count_factors_of_5(i) return total_count # 测试样例 if __name__ == "__main__": test_cases = [10, 15, 20] results = {case: count_trailing_zeros_double_factorial(case) for case in test_cases} print(results) ``` 上述代码通过逐步减少步长的方式模拟了双阶乘的过程,并利用辅助函数 `count_factors_of_5` 来统计每个参与运算的数中含有多少个因子 \( 5 \)。 --- #### 示例运行结果 如果输入测试数据 `[10, 15, 20]`,程序会输出对应的末尾零数量字典 `{10: 2, 15: 3, 20: 4}`。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值