阶乘很简单?恕我直言,阶乘相关的面试题你还真不一定懂!

11.闰年的判定 上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。 阅读详情

阶乘很简单?恕我直言,阶乘相关的面试题你还真不一定懂!

对于如何算 n 的阶乘,只要你知道阶乘的定义,我想你都知道怎么算,但如果在面试中,面试官抛给你一道与阶乘相关,看似简单的算法题,你还真不一定能够给出优雅的答案!本文将分享几道与阶乘相关的案例,且难度递增。

案例一

给定一个整数 N,那么 N 的阶乘 N! 末尾有多少个 0?例如: N = 10,则 N!= 3628800,那么 N! 的末尾有两个0。

有些人心想,这还不简单,直接算出 N!的值,然后用除以 10 来判断多少个 0 就可以了。

有些人则这样想,直接算 N!的值再来除以 10 判断多少个 0 的话肯定会出现溢出问题,于是开始思索:一个数乘以 10 就一定会在末尾产生一个零,于是,我们可以从“哪些数相乘能够得到 10 ”入手。

没错,只有 2 * 5 才会产生 10。

注意,4 5 = 20 也能产生 0 啊,不过我们也可以把 20 进行分解啊,20 = 10 2。

于是,问题转化为 N! 种能够分解成多少对 25,再一步分析会发现,在 N!中能够被 2 整除的数一定比能够被 5 整除的数多,于是问题就转化为求 1…n 这 n 个数中能够被 5 整除的数有多少个,注意,像 25 能够被 5整除两次,所以25是能够产生 2 对 2 5滴。有了这个思路,代码如下:

int f(int n){
    int sum = 0;
    for(int i = 1; i <= n; i++){
        int j = i;
        while(j % 5 == 0){
            sum++;
            j = j / 5;
        }
    }
    return sum;
}

有些人想出了这个规律,很是得意,然而,这还不是面试官要的答案,大家想一个问题,

当 N = 20 时,1~20 可以产生几个 5 ?答是 4 个,此时有 N / 5 = 4。

当 N = 24 时,1~24 可以产生几个 5 ?答是 4 个,此时有 N / 5 = 4。

当 N = 25 时,1~25 可以产生几个 5?答是 6 个,主要是因为 25 贡献了两个 5,此时有 N / 5 + N / 5^2 = 6。

…

可以发现 产生 5 的个数为 sum = N/5 + N/5^2 + N/5^3+….

于是,最优雅的写法应该是这样:

int f(int n){
    int sum = 0;
    while(n! = 0){
        sum += n / 5;
        n = n / 5;
    }
}

这时,你就可以自信这把代码扔给面试官了。

案例2

求 N! 的二进制表示中最低位 1 的位置。例如 3!=6,二进制为 1010,所以 最低位 1 的位置在第二位。

没有思路?请仔细想一下这道题与上道题的关系!

仔细想一下,这道题不也是求末尾有多少个 0 吗?你求出了末尾有多少个0自然知道 1 的位置(0的个数加1就是1的位置了),只不过,这道题是求二进制末尾有多少个 0。

由于是二进制,所以每次乘以 2 末尾就会产生一个 0 。

于是,模仿上面一道题,求 N!含有多少个 2 的个数。心想,幸好我做个类似了,于是一波操作猛如虎,一分钟就写出了代码:

int f(int n){
    int sum = 0;
    while(n! = 0){
        sum += n / 2;
        n = n / 2;
    }
}

面试官:还能在优化吗?

什么鬼?还要在优化?我都 O(logn) 时间复杂度了。

还记得我之前讲解了几道有关位运算的吗?这道题确实可以用位运算来优化,除以 n / 2 == n >> 1。不过位运算的速度快多了,于是,优化后的代码如下:

int f(int n){
    int sum = 0;
    while(n! = 0){
        n >>= 1;
        sum += n;
    }
}

还能在优化吗?

可以,不过我先不讲,因为我觉得,这已经够快了。后面讲其他题可能会把这道题再拿出来讲。

如果你能写出这样的代码,已经算很牛逼了。

案例三

给你一个数 N,输出 N! 的值。

没错,就是这么简单,直接让你求阶乘的值。

这个时候,你就要小心了,千万别一波操作

long long sum = 1;
for(int i = 1; i <= n; i++){
    sum *= i;

}

一个 for 循环,马上搞定。

因为你不知道 n 的范围,有可能你用 long long 也是会溢出的,所以这个时候应该要问一下面试官有没有限定 n 的范围。

面试官:没有限定!

这下好了,这道阶乘的题,难度顿时上升了,说实话,我敢保证大部分人还真没去实现过。所以,今天我就带大家来实现一下,以防以后真的被问到。结果最熟悉的题顿时不知道怎么下手好。

这个时候,我们就必须用字符串来存放所求的值的,在相乘的时候也是用字符串来相乘,说白了,就是要会求两个大整数相乘。

下面我们先来实现一个求两个大整数相乘的函数。一种比较简单的方法就是,像我们小学那会一样,让个位数与另一个数的其他数相乘,然后让十位数与另一个的其他数相乘,最后在把他们进行相加。

阶乘很简单?恕我直言,阶乘相关的面试题你还真不一定懂!

实现代码如下:

    public static String mul(String s1, String s2) {
        // 先把字符串转化为 字符数组。
        char[] c1 = s1.toCharArray();
        char[] c2 = s2.toCharArray();
        int len = c1.length + c2.length;
        // 用来存放两个数的积,字符的初始值为 '\u0000',也就是 0
        char[] c = new char[len];
        // 由于大整数的低位是在字符串的末尾,所以我们从末尾遍历来计算
        for (int i = c1.length - 1; i >= 0; i--) {
            int index = len - 1;
            int res = 0;//用来存放进位
            for (int j = c2.length - 1; j >= 0; j--) {
                int temp = (c1[i]-'0') * (c2[j]-'0') + c[index] + res;
                res = temp / 10;
                c[index--] = (char)(temp % 10);
            }
            // 每趟乘下来的进位要进行保存。
            c[index] = (char)res;
            len--;
        }
        // 最后把c中的字符加上 '0'
        for (int i = 0; i < c.length; i++) {
            c[i] += '0';
        }
        String s = new String(c);
        // n位数乘以m位数得到积位 (m+n)位数或者(n+m-1)位数
        // 我们只需要判断c[0]是否为0,为0则把它舍弃。
        if(c[0] == '0')
            return s.substring(1);
        else
        return s;
    }

注意,一定要自己实现一遍,一定要自己实现一遍,因为原理简单,但手动实现就不一定那么简单了,容易出现bug。

采用这种方法的话,两个大整数相乘的时间复杂度为 O(n),其实还有更快的方法,大概时间复杂度是 O(n^1.6),不过代码有点小复杂。

知道了两个大整数相乘之后,我们再来算我们的阶乘,就好做了,我们每次相乘的时候,只需要把它当作两个大整数重复乘就可以了。代码如下:

    // N 的阶乘
    public static String f(int n) {
        String s = "1";
        Integer t = null;
        for (int i = 2; i <= n; i++) {
            t = i;
            s = 大整数相乘.mul(s,t.toString());
        }
        return s;
    }

    // 大整数相乘
    public static String mul(String s1, String s2) {
        // 先把字符串转化为 字符数组。
        char[] c1 = s1.toCharArray();
        char[] c2 = s2.toCharArray();
        int len = c1.length + c2.length;
        // 用来存放两个数的积,字符的初始值为 '\u0000',也就是 0
        char[] c = new char[len];
        // 由于大整数的低位是在字符串的末尾,所以我们从末尾遍历来计算
        for (int i = c1.length - 1; i >= 0; i--) {
            int index = len - 1;
            int res = 0;//用来存放进位
            for (int j = c2.length - 1; j >= 0; j--) {
                int temp = (c1[i]-'0') * (c2[j]-'0') + c[index] + res;
                res = temp / 10;
                c[index--] = (char)(temp % 10);
            }
            // 每趟乘下来的进位要进行保存。
            c[index] = (char)res;
            len--;
        }
        // 最后把c中的字符加上 '0'
        for (int i = 0; i < c.length; i++) {
            c[i] += '0';
        }
        String s = new String(c);
        // n位数乘以m位数得到积位 (m+n)位数或者(n+m-1)位数
        // 我们只需要判断c[0]是否为0,为0则把它舍弃。
        if(c[0] == '0')
            return s.substring(1);
        else
        return s;
    }

时间复杂度是 O(n^3)。如果要优化的话,主要是在大整数相乘这里进行优化。

总结

是不是觉得,阶乘也没有那么简单了?这三道与阶乘相关的题,应该是比较常见的题吧,今天跟大家分享一波,希望大家有时间的话,自己也用代码实现一下,特别是算 N!。后面会继续跟大家分享一些我觉得不错的算法题以及一些算法技巧,敬请关注。

1~20各个数的阶乘的和 1~20各个数的阶乘的和.....VC++ 上级实验题 立即下载

相关推荐

谷歌Gemini模型免费API调用全攻略:从注册到实战(附代码示例)

本文详细介绍了如何免费调用谷歌Gemini模型的API,从注册获取API密钥到实战应用的全过程。内容涵盖环境准备、基础API调用、多模态处理、高级功能及生产环境实践,帮助开发者高效利用Gemini模型进行代码生成和复杂任务处理。附有代码示例,适合AI开发者和技术爱好者。

weixin_29212429的博客 1606

关于阶乘的面试题总结

阶乘方面的题一直是我最近不太明白的点,因此我便总结了几个关于阶乘方面的面试题供探讨。 面试题: 一、给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。 二、求N!的二进制表示中最低位1的位置。 对于第一道题,一般人的思路会是想着求完N!之后再来看,此时就要考虑是不是溢出的问题,但是我们换一个思路想一想,想一下有什么数字相乘可以等

ArchyLi 1239

Qt 6.5实战:用QMediaPlayer搞定RTSP监控流播放(附LAV Filters解码器避坑指南)

本文详细介绍了如何在Qt 6.5中使用QMediaPlayer实现低延迟RTSP监控流播放,并提供了LAV Filters解码器的配置避坑指南。通过优化缓冲策略和硬件加速设置,显著提升视频流的播放性能和稳定性,适用于工业视觉检测和安防监控等实时场景。

weixin_33712987的博客 401

1到20的阶乘和是多少 php,20的阶乘(1到20的阶乘和结果)

如果不是电脑编程的问题 貌似只能使用计算器得到结果了吧 把计算器的显示位数调大一些 然后1的阶乘加到20的阶乘 即1!+2!+3!+…+20!=2561327494111820313#include void main() { int i,n,sum; n=1;sum=0; for(i=1;i和是:2561327494111820300。zd 以下是版通过C进行的计权算:#include "std...

weixin_32667955的博客 9340

Unity大世界流式加载:工业级架构与优化秘籍

游戏大厂Unity大世界流式加载框架全景解析:从《原神》《和平精英》等标杆案例出发,深入剖析工业级流式加载的完整技术架构。文章系统介绍了大世界分区块管理、异步加载机制、资源优化策略、多平台适配方案,以及业务联动与团队协作流程。重点阐述了Addressable与AssetBundle应用、空间触发器设计、性能自适应等核心技术,并展望AI预测加载、云游戏等未来方向。全面展现了大厂如何通过流式加载技术实现无缝开放世界体验的技术路径与实践经验。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 610

从“点云”到“图像”:华为896线激光雷达的技术飞跃与行业影响浅析

华为发布全球首款896线双光路激光雷达,实现车载感知从"3D点云"到"3D成像"的跨越。该产品采用创新双光路架构,集成广角和长焦单元,单帧点云量达128线产品的7倍,可在55米外识别小狗摇尾巴等细节。实测数据显示,其能识别120米外14厘米低矮障碍物,夜间低反射率目标识别距离提升190%。尽管速腾聚创随后发布更高线数产品,但华为强调实用性和量产可行性,成本仅增加1-2万元。这一突破标志着激光雷达进入大规模应用阶段,将加速高阶智驾功能普及,强化华为在智能汽车领域的技术底

致力于lidar应用开发 213

递归算算20的阶乘

计算20 的阶乘 大多数人第一个想法会是使用for循环实现,当然是没问题的 for循环: function caculator(index){ let sum =1 for(var i=0;i<index;i++){ sum = sum*index } return sum } 但是面试的时候通常面试官会问有没有比的办法,答案是肯定的 递归方法: function diGui (x){ if(x==0){ return 1

qq_35661041的博客 1644

YOLOv8的特征蒸馏代码应用讲解(CWD/MGD/mimic/在线蒸馏/逻辑蒸馏)

基于YOLOv8的逻辑蒸馏、特征蒸馏、在线蒸馏等方法代码介绍。

qq_41920323的博客 2583

20的阶乘是多少_阶乘很简单?恕我直言,阶乘相关的面试题你还真不一定懂!...

来自:苦逼的码农(微信号:di201805)作者:帅地个人简介:一个热爱编程的在校生,我的世界不只有coding,还有writing。目前维护订阅号「苦逼的码农」,专注于写「算法与数据结构」,「Java」,「计算机网络」。对于如何算 n 的阶乘,只要你知道阶乘的定义,我想你都知道怎么算,但如果在面试中,面试官抛给你一道与阶乘相关,看似简单的算法题,你还真不一定能够给出优雅的答案!本文将分...

weixin_39882394的博客 3368

YOLO小目标检测优化:9种实用方案,准确率直接提升15%

小目标检测是个系统工程,没有银弹,但有明确的优化路径。优先搞数据。Copy-Paste + 提升分辨率,这俩加起来成本最低、收益最大,能解决80%的小目标问题。别一上来就改模型结构。调参走在改结构前面。锚框聚类、损失加权、增强优化,这些都是零成本的,先做满了再说改模型的事。P2层是大杀器,但不要轻易用。加了P2层,TensorRT部署、后处理、速度都要跟着调,工程化工作量翻倍。数据和训练做到位还不够,再加也不迟。滑动窗口是兜底的。能从训练端解决的问题,就不要拖到推理端。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 189

Qt6.10 | Qt Bluetooth 蓝牙

本文介绍了QtBluetooth模块的功能和使用方法,包括蓝牙API概述、构建配置(CMake/qmake)、权限管理、平台支持(Linux/macOS特殊处理)、日志设置及许可信息。重点说明Linux平台的后端选择机制,以及macOS上的依赖限制。最后提及蓝牙聊天示例,展示RFCOMM协议通信的实现。全文提供了蓝牙开发的技术要点和注意事项。

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 400

Java最新阶乘很简单?恕我直言,阶乘相关的面试题你还真不一定懂!,java笔试面试BAT

小编精心为大家准备了一手资料以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术【附】架构书籍BAT面试的20道高频数据库问题解析Java面试宝典Netty实战算法BATJ面试要点及Java架构师进阶资料本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取。

2401_84557849的博客 621

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

运算阶乘的代码_阶乘很简单?恕我直言,阶乘相关的面试题你还真不一定懂!...

来自:苦逼的码农(微信号:di201805)作者:帅地个人简介:一个热爱编程的在校生,我的世界不只有coding,还有writing。目前维护订阅号「苦逼的码农」,专注于写「算法与数据结构」,「Java」,「计算机网络」。对于如何算n的阶乘,只要你知道阶乘的定义,我想你都知道怎么算,但如果在面试中,面试官抛给你一道与阶乘相关,看似简单的算法题,你还真不一定能够给出优雅的答案!本文将分...

weixin_39707597的博客 227

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

阶乘很简单?说实话,这几道阶乘相关面试题你还真不一定懂!

对于如何算 n 的阶乘,只要你知道阶乘的定义,我想你都知道怎么算,但如果在面试中,面试官抛给你一道与阶乘相关,看似简单的算法题,你还真不一定能够给出优雅的答案!本文将分享几道与阶乘相关的案例,且难度递增。 案例一 给定一个整数 N,那么 N 的阶乘 N! 末尾有多少个 0?例如: N = 10,则 N!= 3628800,那么 N! 的末尾有两个0。 有些人心想,这还不简单,直接算出 N!的值...

weixin_30451709的博客 103

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

求n的阶乘的算法框图_阶乘很简单?说实话,这几道阶乘相关面试题你还真不一定懂!...

对于如何算 n 的阶乘,只要你知道阶乘的定义,我想你都知道怎么算,但如果在面试中,面试官抛给你一道与阶乘相关,看似简单的算法题,你还真不一定能够给出优雅的答案!本文将分享几道与阶乘相关的案例,且难度递增。案例一 给定一个整数 N,那么 N 的阶乘 N! 末尾有多少个 0?例如: N = 10,则 N!= 3628800,那么 N! 的末尾有两个0。有些人心想,这还不简单,直接算出 N!的值,然后用...

weixin_39524842的博客 569

关于阶乘的两个常见算法及一个相关面试题

阶乘的定义 阶乘是数学中的一个术语。对于一个非负整数n,n的阶乘指的是所有小于等于n的正整数的乘积,记为n!。例如, 符号n!是由Christian Kramp(1760 – 1826)于1808年引入的。 阶乘的严格定义为: 并且0!=1,因为阶乘是针对所有的非负整数。 后者基于一个事实:0个数的乘积为1。这个是很有用的: 递归关系 适用于n = 0的情况; 这个定义使得组合学(combi

jiangxinyu的专栏 1384

2个阶乘什么意思_关于阶乘的两个常见算法及一个相关面试题

阶乘的定义阶乘是数学中的一个术语。对于一个非负整数n,n的阶乘指的是所有小于等于n的正整数的乘积,记为n!。例如,符号n!是由Christian Kramp(1760 – 1826)于1808年引入的。阶乘的严格定义为:并且,因为阶乘是针对所有的非负整数。后者基于一个事实:0个数的乘积为1。这个是很有用的:递归关系 适用于n = 0的情况;这个定义使得组合学(combinatorics)中许多包...

weixin_39616339的博客 1111

阶乘相关的一些面试题

案例一        给定一个整数 N,那么 N 的阶乘 N! 末尾有多少个 0?例如: N = 10,则 N!= 3628800,那么 N! 的末尾有两个0。       有些人心想,这还不简单,直接算出 N!的值,然后用除以 10 来判断多少个 0 就可以了。 &nbsp...

dreamispossible的博客 1164

求n的阶乘的算法框图_阶乘相关的算法题,东哥又整活儿了

Python实战社群Java实战社群长按识别下方二维码,按需求添加扫码关注添加客服进Python社群▲扫码关注添加客服进Java社群▲作者丨labuladong来源丨labuladong读完本文,你可以去 LeetCode 上拿下如下题目:172、阶乘后的零(难度 Easy)793、阶乘后 K 个零(难度 Hard)笔试题中经常看到阶乘相关的题目,今天说两个最常见的题目:1、输入一个...

weixin_39829166的博客 859

程序员面试题(60):不要被阶乘吓倒

阶乘(Factorial)是个很有意思的函数,但是不少人都比较怕它,我们来看看两个与阶乘相关的问题: 1. 给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。 2. 求N!的二进制表示中最低位1的位置。 请点击"我要发言",提交您的解法或者问题。 我要看答案有些人碰到这样的题目会想:是不是要完整计算出N!的值?如果溢出怎么办?事实上,如

yysdsyl的专栏 4122

关于阶乘的两个常见算法及一个相关面试题【转】

http://www.cnblogs.com/anderslly/archive/2008/05/19/factorial-algorithms.html 阶乘的定义 阶乘是数学中的一个术语。对于一个非负整数n,n的阶乘指的是所有小于等于n的正整数的乘积,记为n!。例如, 符号n!是由Christian Kramp(1760 – 1826)于1808年引入的。 阶乘的严格定义为: ...

weixin_30662011的博客 121
上一篇: 8年开发架构师浅析SpringBoot的JVM的内存占用与Docker-spring.io
下一篇: 一个程序员的北漂之路——充满多少泪和水
大G哥
博客等级 码龄9年 5303粉丝 1408原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值