Teaching Kids Programming – (!3+3)*!3=10 – Derangement Algorithms via Dynamic Programming Algorithm


Teaching Kids Programming: Videos on Data Structures and Algorithms

In combinatorial mathematics, a derangement is a permutation of the elements of a set, such that no element appears in its original position. You are given an integer n. There is originally an array consisting of n integers from 1 to n in ascending order, return the number of derangements it can generate.

Example 1:
Input: n = 3
Output: 2
Explanation: The original array is [1,2,3]. The two derangements are [2,3,1] and [3,1,2].

Example 2:
Input: n = 2
Output: 1

Derangement Algorithm via Recursion

Let’s use tex_2d43d32c647168e4f8be88dd46768880 Teaching Kids Programming - (!3+3)*!3=10 - Derangement Algorithms via Dynamic Programming Algorithm to denote the number of ways to put N items in such derangement order aka the i-th item cannot be put in index i. The base conditions are:

tex_6398b0b40d7d71c62de8fad787239985 Teaching Kids Programming - (!3+3)*!3=10 - Derangement Algorithms via Dynamic Programming Algorithm
tex_e05fefefa8d559dbd4453ad2798c0cb1 Teaching Kids Programming - (!3+3)*!3=10 - Derangement Algorithms via Dynamic Programming Algorithm

Now, let’s take a look at the item N. We cannot place it in the last position but we can put it at position 1 to N-1 so N-1 choices. If we put it at K where K is not N, then we have two choices for K, we can swap it with N thus tex_42b0296b8359c0062b284e87b5d0d865 Teaching Kids Programming - (!3+3)*!3=10 - Derangement Algorithms via Dynamic Programming Algorithm or we don’t, thus tex_59c7454ce8f4b698ac032c4b8019eeb5 Teaching Kids Programming - (!3+3)*!3=10 - Derangement Algorithms via Dynamic Programming Algorithm

tex_b3bbce5870f4cf5c2bf26e0a52479b51 Teaching Kids Programming - (!3+3)*!3=10 - Derangement Algorithms via Dynamic Programming Algorithm
so further simplified to:
tex_2608a59b4e3a25425bb419466b9d7c41 Teaching Kids Programming - (!3+3)*!3=10 - Derangement Algorithms via Dynamic Programming Algorithm

Thus, recursive algorithm similar to Fibonacci numbers which can be done in simple Recursion:

def f(n):
    if n in (0, 1):
        return 0
    if n == 2:
        return 1
    return (n - 1) * (f(n-1) + f(n-2))

The time complexity is exponential since we re-calculate the intermediate f values.

Derangement Algorithm via Dynamic Programming

We can simply add a @cache keyword or use a hash map aka dictionary to remember the values so that are not calculated over and over again. This is Top Down Dynamic Programming Algorithm aka Recursion with Memoization:

@cache
def f(n):
    if n in (0, 1):
        return 0
    if n == 2:
        return 1
    return (n - 1) * (f(n-1) + f(n-2))

The Dynamic Programming algorithm can be done in Bottom Up manner. Below uses the Array to calculate and store the derangement values from a smaller N e.g. F(0), F(1), F(2) … F(N)

def f(n):
    if n in (0, 1):
        return 0
    if n == 2:
        return 1
    dp = [0] * (n + 1)
    dp[2] = 1
    for i in range(3, n + 1):
        dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2])
    return dp[-1] # or dp[n]

The time/space complexity is O(N). The f(n) value is only dependent on f(n-1) and f(n-2) the previous two values, similar to Fibonacci Numbers, and thus we can use two variables to store these:

def f(n):
    if n in (0, 1):
        return 0
    if n == 2:
        return 1
    a, b = 0, 1
    for i in range(3, n + 1):
        a, b = b, (a + b) * (i - 1)
    return b

Derangement Algorithms

–EOF (The Ultimate Computing & Technology Blog) —

875 words
Last Post: Teaching Kids Programming - Count Unreachable Pairs of Nodes in an Undirected Graph (Union Find and Disjoint Set Algorithm)
Next Post: Teaching Kids Programming - Recursive Depth First Search Algorithm to Evaluate the Boolean Binary Tree

The Permanent URL is: Teaching Kids Programming – (!3+3)*!3=10 – Derangement Algorithms via Dynamic Programming Algorithm (AMP Version)

Leave a Reply