Topic
- Math
Description
https://leetcode.com/problems/factorial-trailing-zeroes/
Given an integer n
, return the number of trailing zeroes in n!
.
Follow up: Could you write a solution that works in logarithmic time complexity?
Example 1:
Input: n = 3
Output: 0
Explanation: 3! = 6, no trailing zero.
Example 2:
Input: n = 5
Output: 1
Explanation: 5! = 120, one trailing zero.
Example 3:
Input: n = 0
Output: 0
Constraints:
- 0 <= n <= 10⁴
Analysis
方法一:暴力算法(用到Java的BigInteger)。
方法二:分析成阶乘后出现0的情况。
出现0情况是乘子中有5, 10, 15…等5的整数倍的数。
5可与偶数乘子相乘等出10的整数倍,而且偶数个数是明显大大多于5的整数倍的数,于是一个数阶乘后低位出现0的个数有至少有 n / 5 个。
另外注意乘子中有25, 125, 625…5的整数幂的整数倍(如50, 75, 100, 250 …),25 = 5 * 5,125 = 5 * 5 * 5,625 = 5 * 5 * 5 * 5,额外的5需要更多偶数与它们配对。也就是说一个数阶乘后低位出现0的个数有 n / 5 + n / 25 + n / 125 + n / 625… 。这样程序基本成型。
方法三:别人写的,更精简。
Submission
import java.math.BigInteger;
public class FactorialTrailingZeroes {
// 方法一:暴力算法
public int trailingZeroes1(int n) {
int result = 0;
BigInteger num = factorial(n);
while (num.mod(BigInteger.TEN).equals(BigInteger.ZERO)) {
result++;
num = num.divide(BigInteger.TEN);
}
return result;
}
public BigInteger factorial(int n) {
BigInteger product = BigInteger.valueOf(1);
for (int i = n; i > 0; i--)
product = product.multiply(BigInteger.valueOf(i));
return product;
}
// 方法二:根据方法一规律可得
public int trailingZeroes2(int n) {
// if(n == 0) return 0;
int num = (int) (Math.log(n) / Math.log(5));
int result = 0;
while (num > 0)
result += (n / (int) Math.pow(5, num--));
return result;
}
// 方法三:别人写的,更精简
public int trailingZeroes3(int n) {
return n == 0 ? 0 : n / 5 + trailingZeroes3(n / 5);
}
}
Test
import static org.junit.Assert.*;
import org.junit.Test;
public class FactorialTrailingZeroesTest {
@Test
public void test1() {
FactorialTrailingZeroes obj = new FactorialTrailingZeroes();
assertEquals(0, obj.trailingZeroes1(3));
assertEquals(1, obj.trailingZeroes1(5));
assertEquals(0, obj.trailingZeroes1(0));
assertEquals(0, obj.trailingZeroes2(3));
assertEquals(1, obj.trailingZeroes2(5));
assertEquals(0, obj.trailingZeroes2(0));
for(int i = 0; i <= 1000; i++) {
//System.out.println(String.format("trailingZeroes(%d) : %d : %d", i, obj.trailingZeroes1(i), obj.trailingZeroes2(i)));
assertEquals(obj.trailingZeroes1(i), obj.trailingZeroes2(i));
}
}
@Test
public void test2() {
FactorialTrailingZeroes obj = new FactorialTrailingZeroes();
for(int i = 0; i <= 1000; i++) {
assertEquals(obj.trailingZeroes1(i), obj.trailingZeroes3(i));
}
}
@Test
public void testfactorial() {
FactorialTrailingZeroes obj = new FactorialTrailingZeroes();
assertEquals("265252859812191058636308480000000", obj.factorial(30).toString());
}
}