comments | difficulty | edit_url | tags | |||||
---|---|---|---|---|---|---|---|---|
true |
Medium |
|
Given an integer n
, return the number of permutations of the 1-indexed array nums = [1, 2, ..., n]
, such that it's self-divisible.
A 1-indexed array a
of length n
is self-divisible if for every 1 <= i <= n
, gcd(a[i], i) == 1
.
A permutation of an array is a rearrangement of the elements of that array, for example here are all of the permutations of the array [1, 2, 3]
:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
Example 1:
Input: n = 1 Output: 1 Explanation: The array [1] has only 1 permutation which is self-divisible.
Example 2:
Input: n = 2 Output: 1 Explanation: The array [1,2] has 2 permutations and only one of them is self-divisible: nums = [1,2]: This is not self-divisible since gcd(nums[2], 2) != 1. nums = [2,1]: This is self-divisible since gcd(nums[1], 1) == 1 and gcd(nums[2], 2) == 1.
Example 3:
Input: n = 3 Output: 3 Explanation: The array [1,2,3] has 3 self-divisble permutations: [1,3,2], [3,1,2], [2,3,1]. It can be shown that the other 3 permutations are not self-divisible. Hence the answer is 3.
Constraints:
1 <= n <= 12
We can use a binary number
Then, we design a function
We can use the method of memoization search to calculate the value of
In the process of calculating
Otherwise, we enumerate the numbers
Finally, we can get the value of
The time complexity is
class Solution:
def selfDivisiblePermutationCount(self, n: int) -> int:
@cache
def dfs(mask: int) -> int:
i = mask.bit_count() + 1
if i > n:
return 1
ans = 0
for j in range(1, n + 1):
if (mask >> j & 1) == 0 and (i % j == 0 or j % i == 0):
ans += dfs(mask | 1 << j)
return ans
return dfs(0)
class Solution {
private int n;
private Integer[] f;
public int selfDivisiblePermutationCount(int n) {
this.n = n;
f = new Integer[1 << (n + 1)];
return dfs(0);
}
private int dfs(int mask) {
if (f[mask] != null) {
return f[mask];
}
int i = Integer.bitCount(mask) + 1;
if (i > n) {
return 1;
}
f[mask] = 0;
for (int j = 1; j <= n; ++j) {
if ((mask >> j & 1) == 0 && (i % j == 0 || j % i == 0)) {
f[mask] += dfs(mask | 1 << j);
}
}
return f[mask];
}
}
class Solution {
public:
int selfDivisiblePermutationCount(int n) {
int f[1 << (n + 1)];
memset(f, -1, sizeof(f));
function<int(int)> dfs = [&](int mask) {
if (f[mask] != -1) {
return f[mask];
}
int i = __builtin_popcount(mask) + 1;
if (i > n) {
return 1;
}
f[mask] = 0;
for (int j = 1; j <= n; ++j) {
if ((mask >> j & 1) == 0 && (i % j == 0 || j % i == 0)) {
f[mask] += dfs(mask | 1 << j);
}
}
return f[mask];
};
return dfs(0);
}
};
func selfDivisiblePermutationCount(n int) int {
f := make([]int, 1<<(n+1))
for i := range f {
f[i] = -1
}
var dfs func(int) int
dfs = func(mask int) int {
if f[mask] != -1 {
return f[mask]
}
i := bits.OnesCount(uint(mask)) + 1
if i > n {
return 1
}
f[mask] = 0
for j := 1; j <= n; j++ {
if mask>>j&1 == 0 && (i%j == 0 || j%i == 0) {
f[mask] += dfs(mask | 1<<j)
}
}
return f[mask]
}
return dfs(0)
}
function selfDivisiblePermutationCount(n: number): number {
const f: number[] = Array(1 << (n + 1)).fill(-1);
const dfs = (mask: number): number => {
if (f[mask] !== -1) {
return f[mask];
}
const i = bitCount(mask) + 1;
if (i > n) {
return 1;
}
f[mask] = 0;
for (let j = 1; j <= n; ++j) {
if (((mask >> j) & 1) === 0 && (i % j === 0 || j % i === 0)) {
f[mask] += dfs(mask | (1 << j));
}
}
return f[mask];
};
return dfs(0);
}
function bitCount(i: number): number {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
We can rewrite the memoization search in Solution 1 into the form of dynamic programming, define
We enumerate
Finally, we can get the value of
The time complexity is
class Solution:
def selfDivisiblePermutationCount(self, n: int) -> int:
f = [0] * (1 << n)
f[0] = 1
for mask in range(1 << n):
i = mask.bit_count()
for j in range(1, n + 1):
if (mask >> (j - 1) & 1) == 1 and (i % j == 0 or j % i == 0):
f[mask] += f[mask ^ (1 << (j - 1))]
return f[-1]
class Solution {
public int selfDivisiblePermutationCount(int n) {
int[] f = new int[1 << n];
f[0] = 1;
for (int mask = 0; mask < 1 << n; ++mask) {
int i = Integer.bitCount(mask);
for (int j = 1; j <= n; ++j) {
if (((mask >> (j - 1)) & 1) == 1 && (i % j == 0 || j % i == 0)) {
f[mask] += f[mask ^ (1 << (j - 1))];
}
}
}
return f[(1 << n) - 1];
}
}
class Solution {
public:
int selfDivisiblePermutationCount(int n) {
int f[1 << n];
memset(f, 0, sizeof(f));
f[0] = 1;
for (int mask = 0; mask < 1 << n; ++mask) {
int i = __builtin_popcount(mask);
for (int j = 1; j <= n; ++j) {
if (((mask >> (j - 1)) & 1) == 1 && (i % j == 0 || j % i == 0)) {
f[mask] += f[mask ^ (1 << (j - 1))];
}
}
}
return f[(1 << n) - 1];
}
};
func selfDivisiblePermutationCount(n int) int {
f := make([]int, 1<<n)
f[0] = 1
for mask := 0; mask < 1<<n; mask++ {
i := bits.OnesCount(uint(mask))
for j := 1; j <= n; j++ {
if mask>>(j-1)&1 == 1 && (i%j == 0 || j%i == 0) {
f[mask] += f[mask^(1<<(j-1))]
}
}
}
return f[(1<<n)-1]
}
function selfDivisiblePermutationCount(n: number): number {
const f: number[] = Array(1 << n).fill(0);
f[0] = 1;
for (let mask = 0; mask < 1 << n; ++mask) {
const i = bitCount(mask);
for (let j = 1; j <= n; ++j) {
if ((mask >> (j - 1)) & 1 && (i % j === 0 || j % i === 0)) {
f[mask] += f[mask ^ (1 << (j - 1))];
}
}
}
return f.at(-1)!;
}
function bitCount(i: number): number {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}