Count ways to rearrange digits of a number such that it is divisible by 2
Given a positive integer N, count the number of possible distinct rearrangements of the digits of N (in decimal representation), such that the resultant number is divisible by 2.
Note: There is no 0 in the number.
Examples:
Input: N = 957
Output: 0
Explanation: There is no even digit in the number. So no even number can be made.
Input: N = 54321
Output: 48
Approach: The problem can be solved based on the below mathematical idea:
A number is only divisible by 2 when the digit at the rightmost side is divisible by 2. So count the number of even digits in N. Say there are total X digits and M even digits in total. So total number of possible even numbers are (X-1)! * M [because we can put each of the even digit at the end and arrange all other digits in any way].
But there can be several same arrangements. So to avoid this in the calculation we have to divide the value by the factorial of frequency of each digit.
Follow the below steps to solve the problem:
- If N = 0 then return 1.
- Find the count of 2, 4, 6, 8 in N and store it in EvenCount(say).
- Find the count of digits in N and store it in DigitCount(say).
- Store frequency of digits in N in Cnt[] array.
- If EvenCount = 0 then return 0
- Else, store (DigitCount – 1)! * EvenCount in res.
- Now traverse from 0 to 9, and set res = res/fact(Cnt[i]).
- fact(Cnt[i]) is factorial of Cnt[i].
- Return res as the required answer.
Below is the implementation of the above approach
C++
#include <bits/stdc++.h>
using namespace std;
int factorial( int N)
{
return (N == 1 || N == 0) ? 1 : N * factorial(N - 1);
}
long checkPerm( int N)
{
if (N == 0)
return 1;
int EvenCount = 0;
int DigitCount = 0;
vector< int > Cnt(10, 0);
while (N) {
int X = N % 10;
Cnt[X]++;
if ((X % 2) == 0)
EvenCount++;
DigitCount++;
N /= 10;
}
int res = EvenCount
? factorial((DigitCount - 1)) * EvenCount
: 0;
if (res == 0)
return 0;
for ( int i = 0; i < 10; i++) {
res /= factorial(Cnt[i]);
}
return res;
}
int main()
{
int N = 54321;
cout << checkPerm(N);
return 0;
}
|
Java
import java.io.*;
class GFG
{
public static int factorial( int N)
{
return (N == 1 || N == 0 ) ? 1
: N * factorial(N - 1 );
}
public static long checkPerm( int N)
{
if (N == 0 )
return 1 ;
int EvenCount = 0 ;
int DigitCount = 0 ;
int Cnt[] = new int [ 10 ];
while (N > 0 ) {
int X = N % 10 ;
Cnt[X]++;
if ((X % 2 ) == 0 )
EvenCount++;
DigitCount++;
N /= 10 ;
}
int res = EvenCount!= 0 ? factorial((DigitCount - 1 ))
* EvenCount
: 0 ;
if (res == 0 )
return 0 ;
for ( int i = 0 ; i < 10 ; i++) {
res /= factorial(Cnt[i]);
}
return res;
}
public static void main(String[] args)
{
int N = 54321 ;
System.out.print(checkPerm(N));
}
}
|
Python3
import math
def factorial(N):
if (N = = 1 or N = = 0 ):
return 1
return N * factorial(N - 1 )
def checkPerm(N):
if (N = = 0 ):
return 1
EvenCount = 0
DigitCount = 0
Cnt = [ 0 ] * 10
while (N):
X = N % 10
Cnt[X] + = 1
if ((X % 2 ) = = 0 ):
EvenCount + = 1
DigitCount + = 1
N = math.floor(N / 10 )
res = 0
if (EvenCount):
res = factorial((DigitCount - 1 )) * EvenCount
if (res = = 0 ):
return 0
for i in range ( 0 , 10 ):
res = math.floor(res / factorial(Cnt[i]))
return res
N = 54321
print (checkPerm(N))
|
C#
using System;
public class GFG
{
static public int factorial( int N)
{
return (N == 1 || N == 0) ? 1
: N * factorial(N - 1);
}
static public long checkPerm( int N)
{
if (N == 0)
return 1;
int EvenCount = 0;
int DigitCount = 0;
int [] Cnt = new int [10];
Array.Fill< int >(Cnt, 0);
while (N > 0) {
int X = N % 10;
Cnt[X]++;
if ((X % 2) == 0)
EvenCount++;
DigitCount++;
N = (N / 10);
}
int res
= EvenCount > 0
? factorial((DigitCount - 1)) * EvenCount
: 0;
if (res == 0)
return 0;
for ( int i = 0; i < 10; i++) {
res = (res / factorial(Cnt[i]));
}
return res;
}
static public void Main()
{
int N = 54321;
Console.WriteLine(checkPerm(N));
}
}
|
Javascript
const factorial = (N) => {
return (N == 1 || N == 0) ? 1 : N * factorial(N - 1);
}
const checkPerm = (N) => {
if (N == 0)
return 1;
let EvenCount = 0;
let DigitCount = 0;
let Cnt = new Array(10).fill(0);
while (N) {
let X = N % 10;
Cnt[X]++;
if ((X % 2) == 0)
EvenCount++;
DigitCount++;
N = parseInt(N / 10);
}
let res = EvenCount
? factorial((DigitCount - 1)) * EvenCount
: 0;
if (res == 0)
return 0;
for (let i = 0; i < 10; i++) {
res = parseInt(res / factorial(Cnt[i]));
}
return res;
}
let N = 54321;
console.log(checkPerm(N));
|
Time Complexity: O(N!),because the factorial function calculates the factorial of a given number using recursion, which has a time complexity of O(N!). The checkPerm function also has a time complexity of O(N!), since it calls the factorial function multiple times.
Auxiliary Space: O(1)
Optimize approach :
To optimize this above approach, you can make the following changes:
- Use a loop to calculate the factorial of N rather than a recursive function. This will reduce the time complexity of the factorial function from O(N!) to O(N).
- Use a single integer variable to count the number of even digits and the number of digits in N rather than two separate variables. This will reduce the space complexity of the checkPerm function from O(2) to O(1).
- Use a single array to count the number of occurrences of each digit in N rather than an array for each digit. This will reduce the space complexity of the checkPerm function from O(10) to O(1).
Here is the optimized version of the code :
C++
#include<iostream>
using namespace std;
long checkPerm( int N) {
if (N == 0) return 1;
int evenCount = 0;
int digitCount = 0;
int count[10] = {0};
while (N > 0) {
int X = N % 10;
count[X]++;
if ((X % 2) == 0) evenCount++;
digitCount++;
N /= 10;
}
int factorial = 1;
for ( int i = 2; i < digitCount; i++) {
factorial *= i;
}
int res = evenCount != 0 ? factorial * evenCount : 0;
if (res == 0) return 0;
for ( int i = 0; i < 10; i++) {
int factorial2 = 1;
for ( int j = 2; j <= count[i]; j++) {
factorial2 *= j;
}
res /= factorial2;
}
return res;
}
int main() {
int N = 54321;
cout << checkPerm(N);
return 0;
}
|
Java
import java.io.*;
import java.io.*;
class GFG {
public static long checkPerm( int N) {
if (N == 0 ) return 1 ;
int evenCount = 0 ;
int digitCount = 0 ;
int [] count = new int [ 10 ];
while (N > 0 ) {
int X = N % 10 ;
count[X]++;
if ((X % 2 ) == 0 ) evenCount++;
digitCount++;
N /= 10 ;
}
int factorial = 1 ;
for ( int i = 2 ; i < digitCount; i++) {
factorial *= i;
}
int res = evenCount != 0 ? factorial * evenCount : 0 ;
if (res == 0 ) return 0 ;
for ( int i = 0 ; i < 10 ; i++) {
int factorial2 = 1 ;
for ( int j = 2 ; j <= count[i]; j++) {
factorial2 *= j;
}
res /= factorial2;
}
return res;
}
public static void main(String[] args) {
int N = 54321 ;
System.out.print(checkPerm(N));
}
}
|
Python3
def checkPerm(N):
if N = = 0 :
return 1
evenCount = 0
digitCount = 0
count = [ 0 ] * 10
while N > 0 :
X = N % 10
count[X] + = 1
if X % 2 = = 0 :
evenCount + = 1
digitCount + = 1
N / / = 10
factorial = 1
for i in range ( 2 , digitCount):
factorial * = i
res = factorial * evenCount if evenCount ! = 0 else 0
if res = = 0 :
return 0
for i in range ( 10 ):
factorial2 = 1
for j in range ( 2 , count[i] + 1 ):
factorial2 * = j
res / / = factorial2
return res
N = 54321
print (checkPerm(N))
|
C#
using System;
class GFG {
public static long CheckPerm( int N) {
if (N == 0) return 1;
int evenCount = 0;
int digitCount = 0;
int [] count = new int [10];
while (N > 0) {
int X = N % 10;
count[X]++;
if ((X % 2) == 0) evenCount++;
digitCount++;
N /= 10;
}
int factorial = 1;
for ( int i = 2; i < digitCount; i++) {
factorial *= i;
}
int res = evenCount != 0 ? factorial * evenCount : 0;
if (res == 0) return 0;
for ( int i = 0; i < 10; i++) {
int factorial2 = 1;
for ( int j = 2; j <= count[i]; j++) {
factorial2 *= j;
}
res /= factorial2;
}
return res;
}
public static void Main( string [] args) {
int N = 54321;
Console.Write(CheckPerm(N));
}
}
|
Javascript
function checkPerm(N) {
if (N == 0) return 1;
let evenCount = 0;
let digitCount = 0;
let count = new Array(10).fill(0);
while (N > 0) {
let X = N % 10;
count[X]++;
if ((X % 2) == 0) evenCount++;
digitCount++;
N = Math.floor(N / 10);
}
let factorial = 1;
for (let i = 2; i < digitCount; i++) {
factorial *= i;
}
let res = evenCount != 0 ? factorial * evenCount : 0;
if (res == 0) return 0;
for (let i = 0; i < 10; i++) {
let factorial2 = 1;
for (let j = 2; j <= count[i]; j++) {
factorial2 *= j;
}
res /= factorial2;
}
return res;
}
let N = 54321;
console.log(checkPerm(N));
|
Time complexity : O(N), where N is the number of digits in the input number. This is because the factorial function, which calculates the factorial of a given number using a loop, has a time complexity of O(N). The checkPerm function also has a time complexity of O(N), since it iterates through all the digits of the input number to count the number of even digits and the number of occurrences of each digit.
Auxiliary Space : O(1), since it uses a fixed number of variables regardless of the size of the input.
Last Updated :
21 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...