Given a number n, find the last non-zero digit in n!.
Examples:
Input : n = 5
Output : 2
5! = 5 * 4 * 3 * 2 * 1 = 120
Last non-zero digit in 120 is 2.
Input : n = 33
Output : 8
A Simple Solution is to first find n!, then find the last non-zero digit of n. This solution doesn’t work for even slightly large numbers due to arithmetic overflow.
A Better Solution is based on the below recursive formula
Let D(n) be the last non-zero digit in n!
If tens digit (or second last digit) of n is odd
D(n) = 4 * D(floor(n/5)) * D(Unit digit of n)
If tens digit (or second last digit) of n is even
D(n) = 6 * D(floor(n/5)) * D(Unit digit of n)
Illustration of the formula:
For the numbers less than 10 we can easily find the last non-zero digit by the above simple solution, i.e., first computing n!, then finding the last digit.
D(1) = 1, D(2) = 2, D(3) = 6, D(4) = 4, D(5) = 2,
D(6) = 2, D(7) = 4, D(8) = 2, D(9) = 8.
D(1) to D(9) are assumed to be precomputed.
Example 1: n = 27 [Second last digit is even]:
D(27) = 6 * D(floor(27/5)) * D(7)
= 6 * D(5) * D(7)
= 6 * 2 * 4
= 48
Last non-zero digit is 8
Example 2: n = 33 [Second last digit is odd]:
D(33) = 4 * D(floor(33/5)) * D(3)
= 4 * D(6) * 6
= 4 * 2 * 6
= 48
Last non-zero digit is 8
How does the above formula work?
The below explanation provides intuition behind the formula. Readers may Refer http://math.stackexchange.com/questions/130352/last-non-zero-digit-of-a-factorial for complete proof.
14! = 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 *
6 * 5 * 4 * 3 * 2 * 1
Since we are asked about last non-zero digit,
we remove all 5's and equal number of 2's from
factors of 14!. We get following:
14! = 14 * 13 * 12 * 11 * 2 * 9 * 8 * 7 *
6 * 3 * 2 * 1
Now we can get last non-zero digit by multiplying
last digits of above factors!
In n! a number of 2’s are always more than a number of 5’s. To remove trailing 0’s, we remove 5’s and equal number of 2’s.
Let a = floor(n/5), b = n % 5. After removing an equal number of 5’s and 2’s, we can reduce the problem from n! to 2a * a! * b!
D(n) = 2a * D(a) * D(b)
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int dig[] = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8};
int lastNon0Digit( int n)
{
if (n < 10)
return dig[n];
if (((n/10)%10)%2 == 0)
return (6*lastNon0Digit(n/5)*dig[n%10]) % 10;
else
return (4*lastNon0Digit(n/5)*dig[n%10]) % 10;
}
int main()
{
int n = 14;
cout << lastNon0Digit(n);
return 0;
}
|
C
#include<stdio.h>
int dig[] = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8};
int lastNon0Digit( int n)
{
if (n < 10)
return dig[n];
if (((n/10) % 10) % 2 == 0)
return (6*lastNon0Digit(n/5)*dig[n%10]) % 10;
else
return (4*lastNon0Digit(n/5)*dig[n%10]) % 10;
}
int main()
{
int n = 14;
printf ( "%d" ,lastNon0Digit(n));
return 0;
}
|
Java
class GFG
{
static int dig[] = { 1 , 1 , 2 , 6 , 4 , 2 , 2 , 4 , 2 , 8 };
static int lastNon0Digit( int n)
{
if (n < 10 )
return dig[n];
if (((n / 10 ) % 10 ) % 2 == 0 )
return ( 6 * lastNon0Digit(n / 5 )
* dig[n % 10 ]) % 10 ;
else
return ( 4 * lastNon0Digit(n / 5 )
* dig[n % 10 ]) % 10 ;
}
public static void main (String[] args)
{
int n = 14 ;
System.out.print(lastNon0Digit(n));
}
}
|
Python3
dig = [ 1 , 1 , 2 , 6 , 4 , 2 , 2 , 4 , 2 , 8 ]
def lastNon0Digit(n):
if (n < 10 ):
return dig[n]
if (((n / / 10 ) % 10 ) % 2 = = 0 ):
return ( 6 * lastNon0Digit(n / / 5 ) * dig[n % 10 ]) % 10
else :
return ( 4 * lastNon0Digit(n / / 5 ) * dig[n % 10 ]) % 10
return 0
n = 14
print (lastNon0Digit(n))
|
C#
using System;
class GFG {
static int []dig = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8};
static int lastNon0Digit( int n)
{
if (n < 10)
return dig[n];
if (((n / 10) % 10) % 2 == 0)
return (6 * lastNon0Digit(n / 5) *
dig[n % 10]) % 10;
else
return (4 * lastNon0Digit(n / 5) *
dig[n % 10]) % 10;
}
public static void Main ()
{
int n = 14;
Console.Write(lastNon0Digit(n));
}
}
|
PHP
<?php
$dig = array (1, 1, 2, 6, 4,
2, 2, 4, 2, 8);
function lastNon0Digit( $n )
{
global $dig ;
if ( $n < 10)
return $dig [ $n ];
if ((( $n / 10) % 10) % 2 == 0)
return (6 * lastNon0Digit( $n / 5) *
$dig [ $n % 10]) % 10;
else
return (4 * lastNon0Digit( $n / 5) *
$dig [ $n % 10]) % 10;
}
$n = 14;
echo (lastNon0Digit( $n ));
?>
|
Javascript
<script>
let dig = [1, 1, 2, 6, 4, 2, 2, 4, 2, 8];
function lastNon0Digit(n)
{
if (n < 10)
return dig[n];
if ((parseInt(n / 10, 10) % 10) % 2 == 0)
return (6 * lastNon0Digit(parseInt(n / 5, 10))
* dig[n % 10]) % 10;
else
return (4 * lastNon0Digit(parseInt(n / 5, 10))
* dig[n % 10]) % 10;
}
let n = 14;
document.write(lastNon0Digit(n));
</script>
|
Time complexity: O(log n)
Space complexity: O(log n)
A Simple Solution based on recursion having worst-case Time Complexity O(nLog(n)).
Approach:-
- It is given that you have to find the last positive digit. Now a digit is made multiple of 10 if there are 2 and 5. They produce a number with last digit 0.
- Now what we can do is divide each array element into its shortest divisible form by 5 and increase count of such occurrences.
- Now divide each array element into its shortest divisible form by 2 and decrease count of such occurrences. This way we are not considering the multiplication of 2 and a 5 in our multiplication(number of 2’s present in multiplication result upto n is always more than number of 5’s).
- Multiply each number(after removing pairs of 2’s and 5’s) now and store just last digit by taking remainder by 10.
- Now call recursively for smaller numbers by (currentNumber – 1) as parameter.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void callMeFactorialLastDigit( int n, int result[], int sumOf5)
{
int number = n;
if (number == 1)
return ;
while (number % 5 == 0) {
number /= 5;
sumOf5++;
}
while (sumOf5 != 0 && (number & 1) == 0) {
number >>= 1;
sumOf5--;
}
result[0] = (result[0] * (number % 10)) % 10;
callMeFactorialLastDigit(n - 1, result, sumOf5);
}
int lastNon0Digit( int n)
{
int result[] = { 1 };
callMeFactorialLastDigit(n, result, 0);
return result[0];
}
int main()
{
cout << lastNon0Digit(7) << endl;
cout << lastNon0Digit(12) << endl;
return 0;
}
|
C
#include <stdio.h>
void callMeFactorialLastDigit( int n, int result[], int sumOf5)
{
int number = n;
if (number == 1)
return ;
while (number % 5 == 0) {
number /= 5;
sumOf5++;
}
while (sumOf5 != 0 && (number & 1) == 0) {
number >>= 1;
sumOf5--;
}
result[0] = (result[0] * (number % 10)) % 10;
callMeFactorialLastDigit(n - 1, result, sumOf5);
}
int lastNon0Digit( int n)
{
int result[] = { 1 };
callMeFactorialLastDigit(n, result, 0);
return result[0];
}
int main()
{
printf ( "%d\n" ,lastNon0Digit(7));
printf ( "%d" ,lastNon0Digit(12));
return 0;
}
|
Java
import java.io.*;
class GFG {
public static void
callMeFactorialLastDigit( int n, int [] result,
int sumOf5)
{
int number = n;
if (number == 1 )
return ;
while (number % 5 == 0 ) {
number /= 5 ;
sumOf5++;
}
while (sumOf5 != 0 && (number & 1 ) == 0 ) {
number >>= 1 ;
sumOf5--;
}
result[ 0 ] = (result[ 0 ] * (number % 10 )) % 10 ;
callMeFactorialLastDigit(n - 1 , result, sumOf5);
}
public static int lastNon0Digit( int n)
{
int [] result = { 1 };
callMeFactorialLastDigit(n, result, 0 );
return result[ 0 ];
}
public static void main(String[] args)
{
System.out.println(lastNon0Digit( 7 ));
System.out.println(lastNon0Digit( 12 ));
}
}
|
Python3
def callMeFactorialLastDigit(n, result, sumOf5):
number = n
if number = = 1 :
return
while (number % 5 = = 0 ):
number = int (number / 5 )
sumOf5 + = 1
while (sumOf5 ! = 0 and (number & 1 ) = = 0 ):
number >> = 1
sumOf5 - = 1
result[ 0 ] = (result[ 0 ] * (number % 10 )) % 10
callMeFactorialLastDigit(n - 1 , result, sumOf5)
def lastNon0Digit(n):
result = [ 1 ]
callMeFactorialLastDigit(n, result, 0 )
return result[ 0 ]
print (lastNon0Digit( 7 ))
print (lastNon0Digit( 12 ))
|
C#
using System;
class GFG {
static void
callMeFactorialLastDigit( int n, int [] result,
int sumOf5)
{
int number = n;
if (number == 1)
return ;
while (number % 5 == 0) {
number /= 5;
sumOf5++;
}
while (sumOf5 != 0 && (number & 1) == 0) {
number >>= 1;
sumOf5--;
}
result[0] = (result[0] * (number % 10)) % 10;
callMeFactorialLastDigit(n - 1, result, sumOf5);
}
static int lastNon0Digit( int n)
{
int [] result = { 1 };
callMeFactorialLastDigit(n, result, 0);
return result[0];
}
static void Main() {
Console.WriteLine(lastNon0Digit(7));
Console.WriteLine(lastNon0Digit(12));
}
}
|
Javascript
<script>
function callMeFactorialLastDigit(n, result, sumOf5)
{
let number = n;
if (number == 1)
return ;
while (number % 5 == 0) {
number /= 5;
sumOf5++;
}
while (sumOf5 != 0 && (number & 1) == 0) {
number >>= 1;
sumOf5--;
}
result[0] = (result[0] * (number % 10)) % 10;
callMeFactorialLastDigit(n - 1, result, sumOf5);
}
function lastNon0Digit(n)
{
let result = [ 1 ];
callMeFactorialLastDigit(n, result, 0);
return result[0];
}
document.write(lastNon0Digit(7) + "</br>" );
document.write(lastNon0Digit(12));
</script>
|
Time complexity :- O(N)
Space complexity :- O(1)
we used single element array (int[] result = {1}) instead of integer as Java is Strictly Pass by Value!. It does not allow pass by reference for primitive data types. That’s why I used a single element array so that the recursive function can change the value of variable(result here). If we would have taken (int result = 1) then this variable remain unaffected.
This article is contributed by Niteesh kumar & KaaL-EL. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.