Similar Problems

Similar Problems not available

Profitable Schemes - Leetcode Solution

Companies:

LeetCode:  Profitable Schemes Leetcode Solution

Difficulty: Hard

Topics: dynamic-programming array  

Problem statement:

Suppose you have n integers from 1 to n. We define a beautiful arrangement as an array that is constructed by these n numbers successfully if one of the following is true for the ith position (1 ≤ i ≤ n) in this array:

  1. The number at the ith position is divisible by i.
  2. i is divisible by the number at the ith position. Given an integer n, return the number of the beautiful arrangements that you can construct.

Example 1: Input: 2 Output: 2 Explanation: The first beautiful arrangement is [1, 2]: - Number at the 1st position (i=1) is 1, and 1 is divisible by i (i=1). - Number at the 2nd position (i=2) is 2, and 2 is divisible by i (i=2). The second beautiful arrangement is [2, 1]: - Number at the 1st position (i=1) is 2, and 2 is divisible by i (i=1). - Number at the 2nd position (i=2) is 1, and i (i=2) is divisible by 1.

Solution:

The problem involves finding all the beautiful arrangements, and the total count of such beautiful arrangements. The arrays should be constructed such that the two conditions mentioned in the problem statement hold. The brute force approach is to find all possible permutations of the given integers (1 to n), and then check if they satisfy the conditions mentioned in the problem statement.

This approach will not work for larger values of n, as the number of permutations increases exponentially. Thus, we need to come up with an algorithm to efficiently count the total number of beautiful arrangements.

Approach:

To count the total number of beautiful arrangements, we can use a recursive approach. The idea is to start with the first position of the array (i.e., index 1), and then find all the possible numbers that can be placed at this position. We can then recursively move to the next position (i.e., index 2), and again find all the possible numbers that can be placed at this position. We can repeat this process until we reach the end of the array.

To find the possible numbers that can be placed at a given position, we can use a bitmask approach. We can create a bitmask with n bits, where the ith bit is set to 1 if the number i has already been used in the array, and is 0 otherwise. We can then iterate over all the possible numbers that can be placed at the given position, and check if they satisfy the conditions mentioned in the problem statement.

If a number satisfies the conditions, we can mark it as used (set the corresponding bit in the bitmask to 1), and recursively move to the next position. We can then count the number of beautiful arrangements that can be constructed, using this approach.

Implementation:

We can start by defining a recursive function, which takes in the current position (i.e., index), a bitmask indicating which numbers have been used so far, and a count of the number of beautiful arrangements found so far.

int countArrangements(int pos, int used, int count, int n) {
    if (pos > n) {
        count++;
        return count;
    }

    for (int i = 1; i <= n; i++) {
        if (!(used & (1 << i)) && (i % pos == 0 || pos % i == 0)) {
            count = countArrangements(pos + 1, used | (1 << i), count, n);
        }
    }

    return count;
}

In this function, we first check if we have reached the end of the array (i.e., if the current position is greater than n). If we have, we increment the count of beautiful arrangements found and return it.

If we have not reached the end of the array, we iterate over all the possible numbers that can be placed at the current position. We check if the number has not been used before and if it satisfies the conditions mentioned in the problem statement. If it does, we mark it as used and recursively move to the next position.

We can then call this function with the initial parameters of pos = 1, used = 0, count = 0. This will give us the total count of beautiful arrangements that can be constructed.

int countArrangement(int n) {
    return countArrangements(1, 0, 0, n);
}

This function simply calls the countArrangements function with the initial parameters, and returns the count of beautiful arrangements found.

Complexity analysis:

The time complexity of this approach is O(n * 2^n), where n is the number of integers from 1 to n. This is because we are iterating over all possible combinations of the numbers used in the array, and this can be represented as a bitmask of size n.

The space complexity of this approach is O(n), as we are using a bitmask to store which numbers have been used so far.

Profitable Schemes Solution Code

1