前言

首先基于一个事实:我们不可能真的把 n! 的结果计算出来,再去数结果的末尾有几个0;n 很小还好,如果n很大,甚至趋近于无穷大,我们是不可能这样做的。原因主要有二:

  1. 一般计算机的计算能力和存储能力也有限,是计算不出那么大的数的。
  2. 即使计算机能算出来,这样做也很耗时,可能要算很久。

连计算机都算不出来,那我们怎么办呢?别慌,虽然我们不能直接算出结果,但我们可以把问题一步步拆解。

拆解思路

首先,我们想什么情况下会产生一个0?

诶,一个数乘以 10,在末尾就会多出一个 0。而 10 = 5 * 2。

一组数相乘的结果末尾有几个0,取决于这组数因式分解后有**几对 **5 和 2 的因子。

针对于 n! 这个题目,有这样一个事实:把相乘的数因式分解后,2 的个数肯定大于 5 的个数。

所以,这个问题可以拆解为:只要求出因式分解后有几个 5 的因子即可,5的个数即是末尾出现的0的个数。

解法一:直接法

这种解法的思路是:直接将 n! 中的每个数,按照 5 来因式分解,最后把出现的 5 的个数加起来。

public int calculateZeroInFactorial(int n) {int count = 0;// 循环判断所有的乘数for (int i = n; i > 0; i++) {if (i % 5 == 0) {// 如果这个乘数可以对 5 进行因式分解,再看这个乘数可以分解出几个5int a = i;while(a % 5 == 0) {a = a / 5;count++;}}}return count;
}
复制代码

但是这种算法的时间复杂度为 O(nlog(n)),那有没有更快的算法呢?

解法二: log(n) 解法

分析:

  1. n! 这些乘数中,每隔 5 个数,肯定会有一个数至少能拆出一个 5 因子。所以 n / 5 = 至少会出现的 5 的个数。
  2. 上面说至少,因为 n / 5 并不能完全算出 5 因子的个数,比如若某个数 25 = 5 * 5,分解后得到的 5 也算一个,所以能被 25 因式分解相当于会出现 2 个 5 因子,而第一步中除以 5 算个数的时候已经算了一个了,所以相当于比之前会多一个 5 因子。
  3. 依此类推,能被 25 * 5 = 125 因式分解的相当于比之前按 25 因式分解的时候又多出一个 5 因子。能被 125 * 5 = 625 因式分解的相当于比按 125 因式分解时又多出一个 5 因子。还有 625 * 5 …...

所以,n! 的结果可以拆分为多少个 5 因子呢?

n/5 + n/25 + n /125 + n/625 + ….

比如 128!的阶乘的结果末尾有几个0呢?

128/5 +128/25 + 128/125 = 25+5+1 = 31 个

又如:1247! 的阶乘的结果末尾有几个0呢?

1247/5 + 1247/25 + 1247/125 + 1247/625 = 249+49+9+1 = 308 个

public int calculateZeroInLogN(int n) {int count = 0;while (n > 0) {count += n / 5;n /= 5;}return count;
}
复制代码

这种算法的时间复杂度为 O(log(n)),效率会高很多,而且仅需几行代码。

转载于:https://juejin.im/post/5d230f95e51d45108126d2d2

面试题:计算 n!阶乘的结果的末尾有几个0相关推荐

  1. android 计算器显示不全,Android5.0 计算器计算结果不准确和结果末尾的多余的‘0’没有省略的解决方法...

    Android5.0 计算器计算结果不准确和结果末尾的多余的'0'没有省略 一.问题的描述: [测试步骤] 1.进入计算器 2.输入 100-99.9 3.查看计算结果 [测试结果] 1.结果为: 0 ...

  2. 【JAVA】(vip)蓝桥杯试题 基础练习 阶乘计算 BASIC-30 JAVA

    目录 试题 基础练习 阶乘计算 要点 思路 代码(无注释) 代码(含有注释) 代码二,==运行超时,内存也超了==某位同学提出的是使用java的大数类BigInteger 试题 基础练习 阶乘计算 资 ...

  3. Python计算整数阶乘的几种方法比较

    问题本身很简单,主要是通过这个小问题来演示Python的一些用法,例如测试代码运行时间.函数嵌套定义等等. from time import time from math import factori ...

  4. 精度计算——大数阶乘

    精度计算--大数阶乘 摘自一个 ACM函数模板 ,学习记录自己的理解(^U^)ノ~YO 语法:int result=factorial(int n) 参数:n: n的阶乘 返回值:阶乘的结果 注意: ...

  5. 本题要求实现一个计算非负整数阶乘的简单函数

    本题要求实现一个计算非负整数阶乘的简单函数. 函数接口定义: int Factorial( const int N ); 其中N是用户传入的参数,其值不超过12.如果N是非负整数,则该函数必须返回N的 ...

  6. 简单阶乘计算 (本题要求实现一个计算非负整数阶乘的简单函数)

    6.简单阶乘计算 本题要求实现一个计算非负整数阶乘的简单函数. 实现代码: int Factorial(const int N ) {int i,n=1;if(N>=0){for(i=0;i&l ...

  7. 1555:计算双阶乘

    1555:计算双阶乘 Description 定义N的双阶乘: N!!=N*(N-2)*(N-4)*....i(i=1 or i=2) 比如5!!=5*3*1=15 而6!!=6*4*2=48 特别的 ...

  8. Golang大整数计算示例-阶乘

    Golang大整数计算示例-阶乘 代码 解析 运行结果 其他说明 结论 代码 直接上代码: package mainimport "fmt" import "math/b ...

  9. c语言22阶乘太大,C语言计算大数阶乘的方法

    C语言计算大数阶乘的方法,整数,数组,阶乘,本文,格式 C语言计算大数阶乘的方法 易采站长站,站长之家为您整理了C语言计算大数阶乘的方法的相关内容. 本文实例为大家分享了C语言计算大数阶乘的具体代码, ...

最新文章

  1. 从“兔子狮子谁做老板”的故事,看企业管理
  2. down redis集群_Redis总结(十)redis集群-哨兵模式
  3. 如何解决IE地址栏前小图标不显示问题
  4. 后退返回命令数量_Redis | Redis 有序集合相关命令
  5. Javascript:this用法
  6. JAVA 15发布,越来越像C# ?9月排名,C#增幅狠甩JAVA
  7. linux---基础02
  8. Android--List与ArrayList区别(转)
  9. MySQL 8.0安装记录
  10. Template Power
  11. iPad PPT演示录屏踩坑及后续ffmpeg处理
  12. win10 uwp 商业游戏
  13. python斐波那契螺旋线怎么画向日葵心_斐波那契螺旋线的图形作法
  14. 9.数据采集与监控知识点
  15. 在oracle中imp是什么意思,Oracle中的Imp和Expt用法
  16. Android MTK Camera驱动代码分析
  17. 《草书识别》隐私政策
  18. Detectron测试过程(含关键点)
  19. 技术人向顾问/管理者转型的推荐经典书35本
  20. 需求分析第一章_需求概述

热门文章

  1. 一款iPhone App推广中得来的18条经验教训
  2. Nagios_快速配置
  3. 你知道怎么离线安装全局 node 模块吗?
  4. MySQL5.5编译工具configure向cmake过渡指南
  5. linux 系统基础知识 - vgextend命令
  6. 转载:WMS、TMS、OMS、WCS都是什么?
  7. html背景设置为彩色,CSS3 彩色网格背景
  8. win10安装vbox没有虚拟网卡_消失的虚拟网卡
  9. 记一次使用 vue-admin-template 的优化历程
  10. Unity使用自定义资源(.asset)配置数据