面试题:计算 n!阶乘的结果的末尾有几个0
前言
首先基于一个事实:我们不可能真的把 n! 的结果计算出来,再去数结果的末尾有几个0;n 很小还好,如果n很大,甚至趋近于无穷大,我们是不可能这样做的。原因主要有二:
- 一般计算机的计算能力和存储能力也有限,是计算不出那么大的数的。
- 即使计算机能算出来,这样做也很耗时,可能要算很久。
连计算机都算不出来,那我们怎么办呢?别慌,虽然我们不能直接算出结果,但我们可以把问题一步步拆解。
拆解思路
首先,我们想什么情况下会产生一个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) 解法
分析:
- n! 这些乘数中,每隔 5 个数,肯定会有一个数至少能拆出一个 5 因子。所以 n / 5 = 至少会出现的 5 的个数。
- 上面说至少,因为 n / 5 并不能完全算出 5 因子的个数,比如若某个数 25 = 5 * 5,分解后得到的 5 也算一个,所以能被 25 因式分解相当于会出现 2 个 5 因子,而第一步中除以 5 算个数的时候已经算了一个了,所以相当于比之前会多一个 5 因子。
- 依此类推,能被 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相关推荐
- android 计算器显示不全,Android5.0 计算器计算结果不准确和结果末尾的多余的‘0’没有省略的解决方法...
Android5.0 计算器计算结果不准确和结果末尾的多余的'0'没有省略 一.问题的描述: [测试步骤] 1.进入计算器 2.输入 100-99.9 3.查看计算结果 [测试结果] 1.结果为: 0 ...
- 【JAVA】(vip)蓝桥杯试题 基础练习 阶乘计算 BASIC-30 JAVA
目录 试题 基础练习 阶乘计算 要点 思路 代码(无注释) 代码(含有注释) 代码二,==运行超时,内存也超了==某位同学提出的是使用java的大数类BigInteger 试题 基础练习 阶乘计算 资 ...
- Python计算整数阶乘的几种方法比较
问题本身很简单,主要是通过这个小问题来演示Python的一些用法,例如测试代码运行时间.函数嵌套定义等等. from time import time from math import factori ...
- 精度计算——大数阶乘
精度计算--大数阶乘 摘自一个 ACM函数模板 ,学习记录自己的理解(^U^)ノ~YO 语法:int result=factorial(int n) 参数:n: n的阶乘 返回值:阶乘的结果 注意: ...
- 本题要求实现一个计算非负整数阶乘的简单函数
本题要求实现一个计算非负整数阶乘的简单函数. 函数接口定义: int Factorial( const int N ); 其中N是用户传入的参数,其值不超过12.如果N是非负整数,则该函数必须返回N的 ...
- 简单阶乘计算 (本题要求实现一个计算非负整数阶乘的简单函数)
6.简单阶乘计算 本题要求实现一个计算非负整数阶乘的简单函数. 实现代码: int Factorial(const int N ) {int i,n=1;if(N>=0){for(i=0;i&l ...
- 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 特别的 ...
- Golang大整数计算示例-阶乘
Golang大整数计算示例-阶乘 代码 解析 运行结果 其他说明 结论 代码 直接上代码: package mainimport "fmt" import "math/b ...
- c语言22阶乘太大,C语言计算大数阶乘的方法
C语言计算大数阶乘的方法,整数,数组,阶乘,本文,格式 C语言计算大数阶乘的方法 易采站长站,站长之家为您整理了C语言计算大数阶乘的方法的相关内容. 本文实例为大家分享了C语言计算大数阶乘的具体代码, ...
最新文章
- 从“兔子狮子谁做老板”的故事,看企业管理
- down redis集群_Redis总结(十)redis集群-哨兵模式
- 如何解决IE地址栏前小图标不显示问题
- 后退返回命令数量_Redis | Redis 有序集合相关命令
- Javascript:this用法
- JAVA 15发布,越来越像C# ?9月排名,C#增幅狠甩JAVA
- linux---基础02
- Android--List与ArrayList区别(转)
- MySQL 8.0安装记录
- Template Power
- iPad PPT演示录屏踩坑及后续ffmpeg处理
- win10 uwp 商业游戏
- python斐波那契螺旋线怎么画向日葵心_斐波那契螺旋线的图形作法
- 9.数据采集与监控知识点
- 在oracle中imp是什么意思,Oracle中的Imp和Expt用法
- Android MTK Camera驱动代码分析
- 《草书识别》隐私政策
- Detectron测试过程(含关键点)
- 技术人向顾问/管理者转型的推荐经典书35本
- 需求分析第一章_需求概述