Count Derangements (Permutation such that no element appears in its original position)

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 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 recursive relation for it.

countDer(n) = (n - 1) * [countDer(n - 1) + countDer(n - 2)]

How does above recursive relation work?
There are n – 1 ways 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.

  1. 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.
  2. 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 Simple Solution based on above recursive formula.

C++

// A Naive Recursive C++ program 
// to count derangements
#include <bits/stdc++.h>
using namespace std;

int countDer(int n)
{
// Base cases
if (n == 1) return 0;
if (n == 0) return 1;
if (n == 2) return 1;

// countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
return (n - 1) * (countDer(n - 1) + 
                  countDer(n - 2));
}

// Driver Code
int main()
{
    int n = 4;
    cout << "Count of Derangements is " 
         << countDer(n);
    return 0;
}

Java

// A Naive Recursive java 
// program to count derangements
import java.io.*;

class GFG 
{
    
    // Function to count
    // derangements
    static int countDer(int n)
    {
        // Base cases
        if (n == 1) return 0;
        if (n == 0) return 1;
        if (n == 2) return 1;
        
        // countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
        return (n - 1) * (countDer(n - 1) + 
                          countDer(n - 2));
    }
    
    // Driver Code
    public static void main (String[] args)
    {
        int n = 4;
        System.out.println( "Count of Derangements is "
                             +countDer(n));

    }
}

// This code is contributed by vt_m

Python3

# A Naive Recursive Python3 
# program to count derangements

def countDer(n):
    
    # Base cases
    if (n == 1): return 0
    if (n == 0): return 1
    if (n == 2): return 1
    
    # countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
    return (n - 1) * (countDer(n - 1) + 
                      countDer(n - 2))

# Driver Code
n = 4
print("Count of Derangements is ", countDer(n))


# This code is contributed by Azkia Anam.


C#

// A Naive Recursive C#
// program to count derangements
using System;

class GFG 
{
    
    // Function to count
    // derangements
    static int countDer(int n)
    {
        // Base cases
        if (n == 1) return 0;
        if (n == 0) return 1;
        if (n == 2) return 1;
        
        // countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
        return (n - 1) * (countDer(n - 1) + 
                          countDer(n - 2));
    }
    
    // Driver Code
    public static void Main ()
    {
        int n = 4;
        Console.Write( "Count of Derangements is " +
                        countDer(n));

    }
}

// This code is contributed by nitin mittal.

PHP

<?php
// A Naive Recursive PHP program 
// to count derangements

function countDer($n)
{
    
    // Base cases
    if ($n == 1) 
        return 0;
    if ($n == 0)
        return 1;
    if ($n == 2) 
        return 1;
    
    // countDer(n) = (n-1)[countDer(n-1) +
    // der(n-2)]
    return ($n - 1) * (countDer($n - 1) + 
                       countDer($n - 2));
}

    // Driver Code
    $n = 4;
    echo "Count of Derangements is ", countDer($n);

// This code is contributed by nitin mittal.
?>


Output:

Count of Derangements is 9

Time Complexity: T(n) = T(n-1) + T(n-2) which is exponential.
We can observe that this implementation does repeated work. For example see recursion tree for countDer(5), countDer(3) is being 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++

// A Dynamic programming based C++ 
// program to count derangements
#include <bits/stdc++.h>
using namespace std;

int countDer(int n)
{
    // Create an array to store 
    // counts for subproblems
    int der[n + 1];

    // Base cases
    der[0] = 1;
    der[1] = 0;
    der[2] = 1;

    // Fill der[0..n] in bottom up manner 
    // using above recursive formula
    for (int i = 3; i <= n; ++i)
        der[i] = (i - 1) * (der[i - 1] + 
                            der[i - 2]);

    // Return result for n
    return der[n];
}

// Driver code
int main()
{
    int n = 4;
    cout << "Count of Derangements is " 
         << countDer(n);
    return 0;
}

Java

// A Dynamic programming based 
// java program to count derangements
import java.io.*;

class GFG 
{
    
    // Function to count
    // derangements 
    static int countDer(int n)
    {
        // Create an array to store
        // counts for subproblems
        int der[] = new int[n + 1];
    
        // Base cases
        der[0] = 1;
        der[1] = 0;
        der[2] = 1;
    
        // Fill der[0..n] in bottom up 
        // manner using above recursive
        // formula
        for (int i = 3; i <= n; ++i)
            der[i] = (i - 1) * (der[i - 1] + 
                                der[i - 2]);
    
        // Return result for n
        return der[n];
    }
    
    // Driver program
    public static void main (String[] args) 
    {
        int n = 4;
        System.out.println("Count of Derangements is " + 
                            countDer(n));
    
    }
}

// This code is contributed by vt_m

Python3

# A Dynamic programming based Python3
# program to count derangements

def countDer(n):
    
    # Create an array to store
    # counts for subproblems
    der = [0 for i in range(n + 1)]
    
    # Base cases
    der[0] = 1
    der[1] = 0
    der[2] = 1
    
    # Fill der[0..n] in bottom up manner 
    # using above recursive formula
    for i in range(3, n + 1):
        der[i] = (i - 1) * (der[i - 1] + 
                            der[i - 2])
        
    # Return result for n
    return der[n]

# Driver Code
n = 4
print("Count of Derangements is ", countDer(n))

# This code is contributed by Azkia Anam.

C#

 
// A Dynamic programming based 
// C# program to count derangements
using System;

class GFG 
{
    
    // Function to count
    // derangements 
    static int countDer(int n)
    {
        // Create an array to store
        // counts for subproblems
        int []der = new int[n + 1];
    
        // Base cases
        der[0] = 1;
        der[1] = 0;
        der[2] = 1;
    
        // Fill der[0..n] in bottom up 
        // manner using above recursive
        // formula
        for (int i = 3; i <= n; ++i)
            der[i] = (i - 1) * (der[i - 1] + 
                                der[i - 2]);
    
        // Return result for n
        return der[n];
    }
    
    // Driver code
    public static void Main () 
    {
        int n = 4;
        Console.Write("Count of Derangements is " + 
                       countDer(n));
    
    }
}

// This code is contributed by nitin mittal

PHP

<?php
// A Dynamic programming based PHP
// program to count derangements

function countDer($n)
{
    // Create an array to store 
    // counts for subproblems

    // Base cases
    $der[0] = 1;
    $der[1] = 0;
    $der[2] = 1;

    // Fill der[0..n] in bottom up manner 
    // using above recursive formula
    for ($i = 3; $i <= $n; ++$i)
        $der[$i] = ($i - 1) * ($der[$i - 1] + 
                               $der[$i - 2]);

    // Return result for n
    return $der[$n];
}

// Driver code
$n = 4;
echo "Count of Derangements is ",
                    countDer($n);

// This code is contributed by aj_36
?>




Output :

Count of Derangements is 9

Time Complexity : O(n)
Auxiliary Space : O(n)

Thanks to Utkarsh Trivedi for suggesting 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



My Personal Notes arrow_drop_up

Improved By : nitin mittal, jit_t




Recommended Posts:



3.2 Average Difficulty : 3.2/5.0
Based on 53 vote(s)






User Actions