Leetcode 172. Factorial Trailing Zeroes

Problem Explanation

The problem is asking to find the number of trailing zeroes in the factorial of a given number.

A trailing zero is formed by multiplication of two numbers: 5 and 2. These numbers appear many times in a factorial but the number 2 occurs more often than the number 5. Therefore, in a factorial, the number of trailing zeroes can be determined by counting the number of numbers divisible by 5.

Example:

Let's say we're given a number 10.

The factorial of 10 is 3628800. Trailing zeroes are the zeroes which are at the end of the number. Here, the factorial 3628800 has 2 trailing zeroes.

Solution Explanation

The solution uses the concept of recursion. We keep on dividing the number by 5 and add these values until the number is zero. For example, for an input of 25, we divide 25 by 5 to get 5 and then divide 5 by 5 to get 1. Adding up these values, we get 6 which is the number of trailing zeroes in 25!.

C++ Solution

1
2cpp
3class Solution {
4  public:
5    int trailingZeroes(int n) {
6      return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5);
7    }
8};

Java Solution

1
2java
3public class Solution {
4    public int trailingZeroes(int n) {
5        return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5);
6    }
7}

Python Solution

1
2python
3class Solution:
4    def trailingZeroes(self, n: int) -> int:
5        return 0 if n == 0 else n // 5 + self.trailingZeroes(n // 5)

JavaScript Solution

1
2javascript
3var trailingZeroes = function(n) {
4    return n === 0 ? 0 : Math.floor(n / 5) + trailingZeroes(Math.floor(n / 5));
5};

C# Solution

1
2csharp
3public class Solution {
4    public int TrailingZeroes(int n) {
5        return n == 0 ? 0 : n / 5 + TrailingZeroes(n / 5);
6    }
7}

Each of these solutions implements the same logical approach using the syntax of their respective programming languages. The base case for the recursion is when n becomes 0, at which point 0 is returned to end the recusive calls. Otherwise, the function divides n by 5 and adds the result to the recursive call of the function with n divided by 5.This method works because it effectively counts the number of times 5 can factor into n!. Each time 5 factors into n!, a trailing zero is added. Since 5 factors into n! more often than 2, we only need to count the factors of 5 to determine the number of trailing zeros.

Optimization

In terms of optimization, this problem doesn't really need any, as the solution is already quite efficient. The time complexity is O(log n), which is the best we can hope for a problem like this. The space complexity is O(1), excluding the space used by the recursion stack.

However, if we want to avoid using recursion, we can re-write this function to use a loop instead. Here's how we could do it in Python:

1
2python
3class Solution:
4    def trailingZeroes(self, n: int) -> int:
5        count = 0
6        while n > 0:
7            n //= 5
8            count += n
9        return count

This version of the function has the same time complexity, O(log n), but it uses less space because it doesn't need to store extra information in the recursion stack. For large inputs, this could make a noticeable difference in terms of performance. So, in limited memory condition it makes sense to use this iterative method. Similar iterative solutions can be implemented in other languages as well.

To conclude, counting the number of trailing zeros in the factorial of a number can be achieved effectively by counting the number of factors of 5 in n!. This can be done either recursively or iteratively, and the most optimal choice depends on your specific constraints and requirements.


Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.


TA 👨‍🏫