comments | difficulty | edit_url | tags | |||||
---|---|---|---|---|---|---|---|---|
true |
中等 |
|
给定一个整数 n
,返回 下标从 1 开始 的数组 nums = [1, 2, ..., n]
的 可能的排列组合数量,使其满足 自整除 条件。
如果对于每个 1 <= i <= n
,满足 gcd(a[i], i) == 1
,数组 nums
就是 自整除 的。
数组的 排列 是对数组元素的重新排列组合,例如,下面是数组 [1, 2, 3]
的所有排列组合:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
示例 1:
输入:n = 1 输出:1 解释:数组 [1] 只有一个排列,它是自整除的。
示例 2:
输入:n = 2 输出:1 解释:数组 [1,2] 有 2 个排列,但只有其中一个是自整除的: nums = [1,2]:这不是自整除的,因为 gcd(nums[2], 2) != 1。 nums = [2,1]:这是自整除的,因为 gcd(nums[1], 1) == 1 并且 gcd(nums[2], 2) == 1。
示例 3:
输入:n = 3 输出:3 解释:数组 [1,2,3] 有 3 个自整除的排列:[1,2,3]、[2,1,3]、[3,2,1]。 其他 3 个排列不能满足自整除条件。因此答案是 3。
提示:
1 <= n <= 12
我们可以用一个二进制数
那么,我们设计一个函数
我们可以用记忆化搜索的方法来计算
在计算
否则,我们枚举当前排列中还未被使用的数字
最终,我们可以得到
时间复杂度
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;
}
我们可以将方法一中的记忆化搜索改写为动态规划的形式,定义
我们在
最终,我们可以得到
时间复杂度
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;
}