A Derangement is a permutation of n elements, such that no element appears in its original position. For example, a derangement of {0, 1, 2, 3} is {2, 3, 1, 0}.
Given a number n, find the total number of Derangements of a set of n elements.
Examples :
Input: n = 2
Output: 1
For two elements say {0, 1}, there is only one
possible derangement {1, 0}
Input: n = 3
Output: 2
For three elements say {0, 1, 2}, there are two
possible derangements {2, 0, 1} and {1, 2, 0}
Input: n = 4
Output: 9
For four elements say {0, 1, 2, 3}, there are 9
possible derangements {1, 0, 3, 2} {1, 2, 3, 0}
{1, 3, 0, 2}, {2, 3, 0, 1}, {2, 0, 3, 1}, {2, 3,
1, 0}, {3, 0, 1, 2}, {3, 2, 0, 1} and {3, 2, 1, 0}
Let countDer(n) be count of derangements for n elements. Below is the recursive relation to it.
countDer(n) = (n - 1) * [countDer(n - 1) + countDer(n - 2)]
How does above recursive relation work?
There are n – 1 way for element 0 (this explains multiplication with n – 1).
Let 0 be placed at index i. There are now two possibilities, depending on whether or not element i is placed at 0 in return.
- i is placed at 0: This case is equivalent to solving the problem for n-2 elements as two elements have just swapped their positions.
- i is not placed at 0: This case is equivalent to solving the problem for n-1 elements as now there are n-1 elements, n-1 positions and every element has n-2 choices
Below is the simple solution based on the above recursive formula:
C++
#include <bits/stdc++.h>
using namespace std;
int countDer( int n)
{
if (n == 1) return 0;
if (n == 2) return 1;
return (n - 1) * (countDer(n - 1) + countDer(n - 2));
}
int main()
{
int n = 4;
cout << "Count of Derangements is "
<< countDer(n);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int countDer( int n)
{
if (n == 1 ) return 0 ;
if (n == 2 ) return 1 ;
return (n - 1 ) * (countDer(n - 1 ) +
countDer(n - 2 ));
}
public static void main (String[] args)
{
int n = 4 ;
System.out.println( "Count of Derangements is "
+countDer(n));
}
}
|
Python3
def countDer(n):
if (n = = 1 ): return 0
if (n = = 2 ): return 1
return (n - 1 ) * (countDer(n - 1 ) +
countDer(n - 2 ))
n = 4
print ( "Count of Derangements is " , countDer(n))
|
C#
using System;
class GFG
{
static int countDer( int n)
{
if (n == 1) return 0;
if (n == 2) return 1;
return (n - 1) * (countDer(n - 1) +
countDer(n - 2));
}
public static void Main ()
{
int n = 4;
Console.Write( "Count of Derangements is " +
countDer(n));
}
}
|
PHP
<?php
function countDer( $n )
{
if ( $n == 1)
return 0;
if ( $n == 2)
return 1;
return ( $n - 1) * (countDer( $n - 1) +
countDer( $n - 2));
}
$n = 4;
echo "Count of Derangements is " , countDer( $n );
?>
|
Javascript
<script>
function countDer(n)
{
if (n == 1) return 0;
if (n == 2) return 1;
return (n - 1) * (countDer(n - 1) + countDer(n - 2));
}
let n = 4;
document.write( "Count of Derangements is " + countDer(n));
</script>
|
Output
Count of Derangements is 9
Time Complexity: O(2^n) since T(n) = T(n-1) + T(n-2) which is exponential.
Auxiliary Space: O(h) where h= log n is the maximum height of the tree.
We can observe that this implementation does repetitive work. For example, see recursion tree for countDer(5), countDer(3) is being evaluated twice.
cdr() ==> countDer()
cdr(5)
/ \
cdr(4) cdr(3)
/ \ / \
cdr(3) cdr(2) cdr(2) cdr(1)
An Efficient Solution is to use Dynamic Programming to store results of subproblems in an array and build the array in bottom-up manner.
C++
#include <bits/stdc++.h>
using namespace std;
int countDer( int n)
{
int der[n + 1] = {0};
der[1] = 0;
der[2] = 1;
for ( int i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
return der[n];
}
int main()
{
int n = 4;
cout << "Count of Derangements is "
<< countDer(n);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int countDer( int n)
{
int der[] = new int [n + 1 ];
der[ 1 ] = 0 ;
der[ 2 ] = 1 ;
for ( int i = 3 ; i <= n; ++i)
der[i] = (i - 1 ) * (der[i - 1 ] +
der[i - 2 ]);
return der[n];
}
public static void main (String[] args)
{
int n = 4 ;
System.out.println( "Count of Derangements is " +
countDer(n));
}
}
|
Python3
def countDer(n):
der = [ 0 for i in range (n + 1 )]
der[ 1 ] = 0
der[ 2 ] = 1
for i in range ( 3 , n + 1 ):
der[i] = (i - 1 ) * (der[i - 1 ] +
der[i - 2 ])
return der[n]
n = 4
print ( "Count of Derangements is " , countDer(n))
|
C#
using System;
class GFG
{
static int countDer( int n)
{
int []der = new int [n + 1];
der[1] = 0;
der[2] = 1;
for ( int i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
return der[n];
}
public static void Main ()
{
int n = 4;
Console.Write( "Count of Derangements is " +
countDer(n));
}
}
|
PHP
<?php
function countDer( $n )
{
$der [1] = 0;
$der [2] = 1;
for ( $i = 3; $i <= $n ; ++ $i )
$der [ $i ] = ( $i - 1) * ( $der [ $i - 1] +
$der [ $i - 2]);
return $der [ $n ];
}
$n = 4;
echo "Count of Derangements is " ,
countDer( $n );
?>
|
Javascript
<script>
function countDer(n)
{
let der = new Array(n + 1);
der[1] = 0;
der[2] = 1;
for (let i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
return der[n];
}
let n = 4;
document.write(
"Count of Derangements is " + countDer(n)
);
</script>
|
Output
Count of Derangements is 9
Time Complexity : O(n)
Auxiliary Space : O(n)
Thanks to Utkarsh Trivedi for suggesting the above solution.
A More Efficient Solution Without using Extra Space.
As we only need to remember only two previous values So, instead of Storing the values in an array two variables can be used to just store the required previous only.
Below is the implementation of the above approach:
C++
#include <iostream>
using namespace std;
int countDer( int n)
{
if (n == 1 or n == 2) {
return n - 1;
}
int a = 0;
int b = 1;
for ( int i = 3; i <= n; ++i) {
int cur = (i - 1) * (a + b);
a = b;
b = cur;
}
return b;
}
int main()
{
cout << "Count of Derangements is " << countDer(4);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int countDer( int n) {
if (n == 1 || n == 2 ) {
return n- 1 ;
}
int a = 0 ;
int b = 1 ;
for ( int i = 3 ; i <= n; ++i) {
int cur = (i- 1 )*(a+b);
a = b;
b = cur;
}
return b;
}
public static void main (String[] args)
{
int n = 4 ;
System.out.println( "Count of Derangements is " +
countDer(n));
}
}
|
Python3
def countDer(n):
if n = = 1 or n = = 2 :
return n - 1 ;
a = 0
b = 1
for i in range ( 3 , n + 1 ):
cur = (i - 1 ) * (a + b)
a = b
b = cur
return b
n = 4
print ( "Count of Derangements is " , countDer(n))
|
C#
using System;
class GFG{
static int countDer( int n)
{
if (n == 1 || n == 2)
{
return n - 1;
}
int a = 0;
int b = 1;
for ( int i = 3; i <= n; ++i)
{
int cur = (i - 1) * (a + b);
a = b;
b = cur;
}
return b;
}
public static void Main()
{
Console.Write( "Count of Derangements is " +
countDer(4));
}
}
|
Javascript
<script>
function countDer(n)
{
if (n == 1 || n == 2)
{
return n - 1;
}
let a = 0;
let b = 1;
for (let i = 3; i <= n; ++i)
{
let cur = (i - 1) * (a + b);
a = b;
b = cur;
}
return b;
}
document.write( "Count of Derangements is "
+ countDer(4));
</script>
|
Output
Count of Derangements is 9
Time Complexity: O(n)
Auxiliary Space: O(1), since no extra space has been taken.
Thanks to Shubham Kumar for suggesting the above solution.
References:
https://en.wikipedia.org/wiki/Derangement
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
20 Jul, 2022
Like Article
Save Article