Problem Description
Given an integer n, return the number of permutations of the 1-indexed array nums = [1, 2, ..., n] such that the permutation is self-divisible. An array is self-divisible if for every index i (1 <= i <= n), the greatest common divisor (gcd) of the element at that index and the index itself equals 1.
Key Insights
- Use backtracking to generate permutations while enforcing the self-divisible condition.
- Use bitmasking to track the numbers used so far.
- Use memoization (dynamic programming) to avoid redundant processing.
- With n <= 12, the state-space (n * 2^n) is acceptable.
Space and Time Complexity
Time Complexity: O(n * 2^n) in the worst case since each state is derived from a bitmask of n bits. Space Complexity: O(2^n) for the memoization cache, plus O(n) for recursion stack.
Solution
We use a DFS (Depth-First Search) based backtracking approach enhanced with bitmasking to represent which numbers have been used so far. For each recursive call, the current position in the permutation is determined by the number of bits set in the bitmask. For each number not yet used, we check if the gcd of the number and the current position (1-indexed) equals 1. If it does, we mark the number as used (by setting the corresponding bit) and recursively process the next position. We employ memoization to cache the result of each bitmask state, ensuring that each state is computed only once, drastically reducing the number of recursive calls.
Code Solutions
Below are solutions in Python, JavaScript, C++, and Java with detailed line-by-line comments.