博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面试题:计算 n!阶乘的结果的末尾有几个0
阅读量:5135 次
发布时间:2019-06-13

本文共 1526 字,大约阅读时间需要 5 分钟。

前言

首先基于一个事实:我们不可能真的把 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 进行因式分解,再看这个乘数可以分解出几个5      int 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

你可能感兴趣的文章
当前记录已被另一个用户锁定
查看>>
Bootstrap
查看>>
Node.js 连接 MySQL
查看>>
ACM-ICPC 2018 world final A题 Catch the Plane
查看>>
那些年,那些书
查看>>
面向对象六大基本原则的理解
查看>>
注解小结
查看>>
java代码编译与C/C++代码编译的区别
查看>>
Bitmap 算法
查看>>
转载 C#文件中GetCommandLineArgs()
查看>>
list control控件的一些操作
查看>>
精读《useEffect 完全指南》
查看>>
SNF快速开发平台MVC-EasyQuery-拖拽生成SQL脚本
查看>>
DrawerLayout实现双向侧滑
查看>>
MySQL入门很简单-触发器
查看>>
LVM快照(snapshot)备份
查看>>
绝望的第四周作业
查看>>
一月流水账
查看>>
数论四大定理
查看>>
npm 常用指令
查看>>