WalzoneInterview Prep
πŸ“ž Interviewing soon? Practice with a realistic AI mock phone interview β€” it calls you, then scores you. First 15 min FREE β†’

Dynamic Programming Β· Advanced Β· question 56 of 100

How can you use dynamic programming to solve the Count Derangements problem? Implement the solution.?

πŸ“• Buy this interview preparation book: 100 Dynamic Programming questions & answers β€” PDF + EPUB for $5

The Count Derangements problem can be stated as follows: given a set of n elements, how many permutations of the set exist where no element appears in its original position? A permutation that satisfies this condition is called a derangement.

Dynamic programming can be used to solve this problem because the solution to the problem depends on the solution to its smaller subproblems. Specifically, we can use memoization to store the results of subproblems and use them to avoid redundant computations.

Let d(n) be the number of derangements of a set of n elements. We can express the number of derangements for n in terms of its solutions for smaller problems. For example, we can consider what happens when we place the first element in any of the n - 1 remaining positions. If we place it in position i, then we have two options for placing the element that was initially in position i: either place it in the first position, which means that we have a subproblem with n - 2 elements, or we place it somewhere other than the first position, which means that we have a subproblem with n - 1 elements. In this analysis, we can see that the solution to the problem for n depends on the solutions to two smaller subproblems (n - 1 and n - 2).

Using memoization, we can avoid computing the same subproblems multiple times. We can create an array or hashmap where we store the solutions to subproblems as we compute them, so that we can reuse them later if necessary. We can start with the base cases d(0) = 1 and d(1) = 0, and compute the solutions for larger values of n recursively as follows:

public static int countDerangementsMemoized(int n, Map<Integer, Integer> memo) {
    if (n == 0) {
        return 1;
    } else if (n == 1) {
        return 0;
    } else if (memo.containsKey(n)) {
        return memo.get(n);
    } else {
        int derangements = (n - 1) * (countDerangementsMemoized(n - 1, memo) + countDerangementsMemoized(n - 2, memo));
        memo.put(n, derangements);
        return derangements;
    }
}

Here, we use a Map<Integer, Integer> to store the results of previously computed subproblems. If the solution for the subproblem n is already in the memo, we simply return it; otherwise, we compute it recursively using the formula for computing the derangements.

To call this function, we can use:

int n = 5;
Map<Integer, Integer> memo = new HashMap<>();
int derangements = countDerangementsMemoized(n, memo);
System.out.println("Number of derangements of " + n + " elements: " + derangements);

This implementation has a time complexity of O(n), as each subproblem is computed only once and stored in the memo. Without memoization, the time complexity would be O(2n), as we would need to compute each subproblem multiple times.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Dynamic Programming interview β€” then scores it.
πŸ“ž Practice Dynamic Programming β€” free 15 min
πŸ“• Buy this interview preparation book: 100 Dynamic Programming questions & answers β€” PDF + EPUB for $5

All 100 Dynamic Programming questions Β· All topics