leetcode [Factorial Trailing Zeroes]

本文介绍了一种高效计算阶乘结果尾数零数量的方法。通过分析5及其幂次作为因子的出现次数来确定尾数中零的数量,提供了解决问题的清晰步骤和示例。

/*
The idea is:
    1.The ZERO comes from 10.
    2.The 10 comes from 2 x 5
    3.And we need to account for all the products of 5 and 2. likes 4×5 = 20 ...
    4.So, if we take all the numbers with 5 as a factor, we'll have way more than enough even numbers to pair with them to get factors of 10
Example One
How many multiples of 5 are between 1 and 23? There is 5, 10, 15, and 20, for four multiples of 5. Paired with 2's from the even factors, this makes for four factors of 10, so: 23! has 4 zeros.

Example Two
How many multiples of 5 are there in the numbers from 1 to 100?
because 100 ÷ 5 = 20, so, there are twenty multiples of 5 between 1 and 100.
but wait, actually 25 is 5×5, so each multiple of 25 has an extra factor of 5, e.g. 25 × 4 = 100,which introduces extra of zero.
So, we need know how many multiples of 25 are between 1 and 100? Since 100 ÷ 25 = 4, there are four multiples of 25 between 1 and 100.
Finally, we get 20 + 4 = 24 trailing zeroes in 100!
The above example tell us, we need care about 5, 5×5, 5×5×5, 5×5×5×5 ....

Example Three
By given number 4617.
5^1 : 4617 ÷ 5 = 923.4, so we get 923 factors of 5
5^2 : 4617 ÷ 25 = 184.68, so we get 184 additional factors of 5
5^3 : 4617 ÷ 125 = 36.936, so we get 36 additional factors of 5
5^4 : 4617 ÷ 625 = 7.3872, so we get 7 additional factors of 5
5^5 : 4617 ÷ 3125 = 1.47744, so we get 1 more factor of 5
5^6 : 4617 ÷ 15625 = 0.295488, which is less than 1, so stop here.
Then 4617! has 923 + 184 + 36 + 7 + 1 = 1151 trailing zeroes.
*/



解法一:遇到大数会超时

public class Solution {
    public int trailingZeroes(int n) {
        int res = 0;
        //因为阶乘里面只有出现5和0尾数中才能出现0;所以以5个为1组,每一组是相乘的关系
        //所以每一组中出现了可能的情况让res增加相应的量,最终能到得res
        //循环时,每一次i增5,所以时间复杂度是log5(N),时间复杂度是对数级的,满足要求
        for(int i = 5; i <= n; i += 5){
        	//尾数为0的不用管了,只用求出本身尾数有多少个0即可,因为这一组只可能有本身尾数那些个数的0
        	//对于每一组,将i(尾数为5)乘2,4,因为只有2,4与5相乘尾数才能有0,
        	//不用像下面的错解去找125,25(因为特殊情况列举不完)啥的了
        	//这里有个错误:每次乘8=2*2*2,结合最上面注释思路的分析,最多只能产生3个0,无论i为多大
        	//所以对于i,应该找i的因子有多少个5,而2在前面一定存在很多没用完的,一定可以满足
        	//尾数为0的可以统一起来,一个道理,50*2=100,但若只算50末尾的0,则只有一个0,错误
        	
        	/*int temp = i;//错误的
        	if(i % 10 == 0){//末位为0
        		temp = temp * 8 * 6;
        	}
        	else{//末位为5
        		temp = temp * 4 * 2;
        	}
        	int tailZeroCount = 0;
        	while(temp != 0 && temp % 10 == 0){//计算一个数的尾部的0的个数
        		tailZeroCount++;
        		temp = temp / 10;
        	}
        	res += tailZeroCount;*/
        	
        	//修改了错误后的,还是有错,尾数为0的不能单独算0,要合起来
        	/*int temp = i;
        	if(i % 10 == 0){//末位为0
        		temp = i;
            	int tailZeroCount = 0;
            	while(temp != 0 && temp % 10 == 0){//计算一个数的尾部的0的个数
            		tailZeroCount++;
            		temp = temp / 10;
            	}
            	System.out.println(i + " tailZeroCount :" + tailZeroCount);
            	res += tailZeroCount;
        	}
        	else{//末位为5
        		int count_5 = 0;
        		temp = i;
        		int exponent_5 = 5;
        		while(temp % exponent_5 == 0){//计算一个数有多少个因子是5,不是while(temp % exponent_5 != 0)
        			count_5 ++;
        			exponent_5 *= 5;
        		}
        		System.out.println(temp + " count_5 :" + count_5);
        		res += count_5;
        	}*/
        	int temp = i;
        	int count_5 = 0;
        	temp = i;
        	int exponent_5 = 5;
        	while(temp % exponent_5 == 0){//计算一个数有多少个因子是5,不是while(temp % exponent_5 != 0)
        		count_5 ++;
        		exponent_5 *= 5;
        	}
        	//System.out.println(temp + " count_5 :" + count_5);
        	res += count_5;
        	
        }
        return res;
    }
    /*public int trailingZeroes(int n) {//错解
        int res = 0;
        for(int i = 5; i <= n; i += 5){
        	if(i % 125 == 0) res += 3;
        	else if(i % 25 == 0) res += 2;
        	else if(i % 5 == 0) res += 1;
        }
        return res;
    }*/
}
解法二(正确):

public class Solution {
	int trailingZeroes(int n) {
	    int result = 0;
	    for(long i=5; n/i>0; i*=5){//加上有多少个5的因子
	        result += (n/i);
	    }
	    return result;
	}
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值