• 172.阶乘后的零 | 793.阶乘函数后k个零


    172.阶乘后的零

    给定一个整数 n ,返回 n! 结果中尾随零的数量。

    提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1

    示例 1:

    输入:n = 3
    输出:0
    解释:3! = 6 ,不含尾随 0
    示例 2:

    输入:n = 5
    输出:1
    解释:5! = 120 ,有一个尾随 0

     思路:

    n!中尾随0的数量 = n!可以分解出因子5的个数

    因为有因子2和因子5,2X5=10,就可以提供一个0,而n!中只要是偶数就至少可以提供一个因子2,即因子2比因子5多的多,所以n!中的因子5的个数就等于n!中尾随0的个数(拿到一个因子5就可以和因子2凑出一个尾随0)。

    1. class Solution {
    2. public:
    3. //n!的结果中尾随0的数量 = n!可以分解出因子5的个数
    4. //例子:125!=125*124*123*...*2*1
    5. /*
    6. 125/5=25,5的倍数肯定可以提供一个因子5,如:5,10,15,20,25...
    7. 125/25=5,25的倍数肯定可以提供两个因子5,如:25,50,75,100,125
    8. 125/125=1,125的倍数肯定可以提供三个因子5,如:125
    9. 所以125!共可以提供25+5+1=31个因子5,也就有31个尾随0。
    10. */
    11. int trailingZeroes(int n) {
    12. int res=0;
    13. int dis=5;
    14. while(dis<=n)
    15. {
    16. res+=n/dis;
    17. dis*=5;
    18. }
    19. return res;
    20. }
    21. };

    793.阶乘函数后k个零

     f(x) 是 x! 末尾是 0 的数量。回想一下 x! = 1 * 2 * 3 * ... * x,且 0! = 1 。

    例如, f(3) = 0 ,因为 3! = 6 的末尾没有 0 ;而 f(11) = 2 ,因为 11!= 39916800 末端有 2 个 0 。
    给定 k,找出返回能满足 f(x) = k 的非负整数 x 的数量。

    示例 1:

    输入:k = 0
    输出:5
    解释:0!, 1!, 2!, 3!, 和 4! 均符合 k = 0 的条件。
    示例 2:

    输入:k = 5
    输出:0
    解释:没有匹配到这样的 x!,符合 k = 5 的条件。

    思路:二分搜索

    要求有多少个数满足阶乘后的0的个数等于k,就是在求满足条件的数中,最小的数是多少,最大的数是多少,最大值最小值一减,差就是结果。

    因为在穷举 n = 1 ~ LONG_MAX 的过程中,随着 n 的增加,n! 肯定是递增的,阶乘后的0的个数肯定也是递增的,所以可以利用二分查找,找到符合条件的数的最小值(搜索左侧边界),找到符合条件的数的最大值(搜索右侧边界)。

    1. class Solution {
    2. public:
    3. long countZero(long n)//返回n!后的0的个数
    4. {
    5. long res=0;
    6. long dis=5;
    7. while(dis<=n)
    8. {
    9. res+=n/dis;
    10. dis*=5;
    11. }
    12. return res;
    13. }
    14. int preimageSizeFZF(int k)
    15. {
    16. return rightBound(k)-leftBound(k)+1;
    17. }
    18. long rightBound(int k)//搜索右侧边界
    19. {
    20. long low=0;
    21. long high=LONG_MAX;
    22. while(low//左闭右开区间
    23. {
    24. long mid=low+(high-low)/2;
    25. if(countZero(mid)>k)
    26. {
    27. high=mid;
    28. }
    29. else if(countZero(mid)
    30. {
    31. low=mid+1;
    32. }
    33. else//找到了符合条件的数,但是不返回,依然向右逼近
    34. {
    35. low=mid+1;
    36. }
    37. }
    38. return low-1;
    39. }
    40. long leftBound(int k)//搜索左侧边界
    41. {
    42. long low=0;
    43. long high=LONG_MAX;
    44. while(low//左闭右开区间
    45. {
    46. long mid=low+(high-low)/2;
    47. if(countZero(mid)
    48. {
    49. low=mid+1;
    50. }
    51. else if(countZero(mid)>k)
    52. {
    53. high=mid;
    54. }
    55. else//找到符合条件的数,但是不返回,依然向左逼近
    56. {
    57. high=mid;
    58. }
    59. }
    60. return low;
    61. }
    62. };
  • 相关阅读:
    MySql数据库-SQL函数
    Linux计划任务管理,网络管理
    Git学习笔记9
    go语言下载安装
    Springboot+Mybatis处理复杂数据类型(Map、List等)
    发布订阅模式
    rust字符串
    JVM----GC(垃圾回收)详解
    Spring cloud学习笔记(服务注册与发现框架Eureka)
    C陷阱:数组越界遍历,不报错却出现死循环?从内存解析角度看数组与局部变量之“爱恨纠葛”
  • 原文地址:https://blog.csdn.net/weixin_50437588/article/details/126751306