阶乘的尾随零点

时间:2015-01-05 18:35:54

标签: java performance integer

我正在尝试解决这个编码问题: 给定整数n,返回n!

中的尾随零的数量

以下是我的代码(使用wiki link编写代码)

    public int trailingZeroes(int n) {
        int count = 0, i = 5;
        while(i<=n){
            count+= n/i;
            i*=5;
        }
        return count;
   }

这适用于所有测试用例,除非n = Integer.MAX_VALUE,我得到了一个TLE。如何修复此代码以使其涵盖该测试用例。我在网上看到了五篇文章,一切似乎都与我的方法一致。

非常感谢。

所以,我遵循了long / BigInteger方法(谢谢你们):

    public int trailingZeroes(int n) {
    long count = 0;
    for(long i= 5; n/i >= 1; i= i*5){
        count+= n/i;
    }
    return (int)count;
}

7 个答案:

答案 0 :(得分:4)

正如Iaune所观察到的,当nInteger.MAX_VALUE时,您的循环永远不会终止,因为没有int大于该数字(根据定义)。您应该能够重构循环以避免该问题。例如,这是相同的基本方法,但颠倒过来:

public int trailingZeroes(int n) {
    int count = 0;

    while (n > 0) {
        n /= 5;
        count += n;
    }

    return count;
}

答案 1 :(得分:3)

您不能编写for循环计数器为int且上限为<= Integer.MAX_VALUE的for或while循环。

简单增量(计数器++)会发生的事情是循环计数器设置为该值,正文执行然后计数器递增,这导致负数,Integer.MIN_VALUE。然后一切都重复发生。

当循环计数器的数量增加时,可能会发生其他奇怪的事情。 1或(如此处)乘以:int循环计数器只能保持值>&gt; Integer.MAX_VALUE的

考虑另一种迭代这些数字的方法。或者单独处理MAX_VALUE。

答案 2 :(得分:2)

您的问题是,i足够大(超过Integer.MAX_INT / 5)后,行i*=5;会导致i溢出到“错误”值。有问题的值是5到14次幂,即6103515625,但溢出到1808548329。

这样做的结果是循环只是永远执行。 i永远不会成为<= Integer.MAX_INT的值,因为没有int

为避免这种情况,您需要i作为比int更大的数据类型。如果您将原始代码中的icount更改为long,则可以正常使用。当然,BigInteger也可以。

答案 3 :(得分:0)

public static void main(String[] args) {
    int result = findFactorialTrailingZero(100);

    System.out.println("no of trailing zeros are " + result);


}

public static int findFactorialTrailingZero(int no) {
    int zeros = no / 5;

    int zeroIncrementNo = 25;
    int zerosIncrementFactor = 1;
    int nextZeroIncrenent = 5;

    for (int i = 1;no >= zeroIncrementNo; i++) {
        zeros=zeros+zerosIncrementFactor;
        zeroIncrementNo=25*(i+1);

        if(i+1==nextZeroIncrenent){
            zerosIncrementFactor++;
            nextZeroIncrenent=nextZeroIncrenent*5;
        }

    }
    return zeros;

答案 4 :(得分:0)

public class FactorialNumberTrailingZeros {

    public static void main(String[] args) {
        System.out.println(trailingZeroes(1000020));
    }

    private static int trailingZeroes(int n) {
        int count = 0;
        while (n > 0 && (n % 10 == 0)) {
            n /= 10;
            count ++;
        }
        return count;
    }
}

答案 5 :(得分:-1)

   /*
    [n/5]+[n/25]+[n/125]+....
    if n<25 then [n/5]
    if n<125 then [n/5]+[n/25]
    if n<625 then [n/5]+[n/25]+[n/125]
    */

#include<bits/stdc++.h>
#include<iostream>
using namespace std;

int countTrailingZeroes(int n)
{
    int res=0;                             
    for(int i=5;i<=n;i=i*5){
         res=res+n/i;
    }
    return res;
}
int main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n;
cin>>n;
cout<<countTrailingZeroes(n);

return 0;
}

输出

25
6

说明: 25!=1.551121e+25 即包含 6 个尾随零

答案 6 :(得分:-1)

这是我的python代码,可以解决您的问题:

    def check(n):
        j,ans=5,0
        while j<=n:
            ans=ans+n//j
            j=j*5
        return ans