Skip to content

Commit e32f004

Browse files
authored
feat: add solutions to lc problem: No.2992 (doocs#2179)
No.2992.Number of Self-Divisible Permutations
1 parent d799290 commit e32f004

14 files changed

+870
-74
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
# [2992. Number of Self-Divisible Permutations](https://leetcode.cn/problems/number-of-self-divisible-permutations)
2+
3+
[English Version](/solution/2900-2999/2992.Number%20of%20Self-Divisible%20Permutations/README_EN.md)
4+
5+
## 题目描述
6+
7+
<!-- 这里写题目描述 -->
8+
9+
<p>Given an integer <code>n</code>, return <em>the number of <strong>permutations</strong> of the <strong>1-indexed</strong> array</em> <code>nums = [1, 2, ..., n]</code><em>, such that it&#39;s <strong>self-divisible</strong></em>.</p>
10+
11+
<p>Array <code>nums</code> is <strong>self-divisible</strong> if for every <code>1 &lt;= i &lt;= n</code>, <strong>at least</strong> one of the following conditions holds:</p>
12+
13+
<ul>
14+
<li><code>nums[i] % i == 0</code></li>
15+
<li><code>i % nums[i] == 0</code></li>
16+
</ul>
17+
18+
<p>A <strong>permutation</strong> of an array is a rearrangement of the elements of that array, for example here are all of the permutations of the array <code>[1, 2, 3]</code>:</p>
19+
20+
<ul>
21+
<li><code>[1, 2, 3]</code></li>
22+
<li><code>[1, 3, 2]</code></li>
23+
<li><code>[2, 1, 3]</code></li>
24+
<li><code>[2, 3, 1]</code></li>
25+
<li><code>[3, 1, 2]</code></li>
26+
<li><code>[3, 2, 1]</code></li>
27+
</ul>
28+
29+
<p>&nbsp;</p>
30+
<p><strong class="example">Example 1:</strong></p>
31+
32+
<pre>
33+
<strong>Input:</strong> n = 1
34+
<strong>Output:</strong> 1
35+
<strong>Explanation:</strong> The array [1] has only 1 permutation which is self-divisible.
36+
</pre>
37+
38+
<p><strong class="example">Example 2:</strong></p>
39+
40+
<pre>
41+
<strong>Input:</strong> n = 2
42+
<strong>Output:</strong> 2
43+
<strong>Explanation:</strong> The array [1,2] has 2 permutations both of which are self-divisible:
44+
nums = [1,2]: This is self-divisible since nums[1] % 1 == 0 and nums[2] % 2 == 0.
45+
nums = [2,1]: This is self-divisible since nums[1] % 1 == 0 and 2 % nums[2] == 0.
46+
</pre>
47+
48+
<p><strong class="example">Example 3:</strong></p>
49+
50+
<pre>
51+
<strong>Input:</strong> n = 3
52+
<strong>Output:</strong> 3
53+
<strong>Explanation:</strong> The array [1,2,3] has 3 self-divisble permutations: [1,2,3], [2,1,3], [3,2,1].
54+
It can be shown that the other 3 permutations are not self-divisible. Hence the answer is 3.
55+
</pre>
56+
57+
<p>&nbsp;</p>
58+
<p><strong>Constraints:</strong></p>
59+
60+
<ul>
61+
<li><code>1 &lt;= n &lt;= 15</code></li>
62+
</ul>
63+
64+
## 解法
65+
66+
<!-- 这里可写通用的实现逻辑 -->
67+
68+
**方法一:状态压缩 + 记忆化搜索**
69+
70+
我们可以用一个二进制数 $mask$ 来表示当前排列的状态,其中第 $i$ 位为 $1$ 表示数字 $i$ 已经被使用,为 $0$ 表示数字 $i$ 还未被使用。
71+
72+
那么,我们设计一个函数 $dfs(mask)$,表示从当前排列的状态 $mask$ 开始,能够构造出的满足题目要求的排列的数量。答案即为 $dfs(0)$。
73+
74+
我们可以用记忆化搜索的方法来计算 $dfs(mask)$ 的值。
75+
76+
在计算 $dfs(mask)$ 的过程中,我们用 $i$ 表示当前要加入排列的是第几个数字,如果 $i \gt n$,说明排列已经构造完毕,我们可以返回 $1$。
77+
78+
否则,我们枚举当前排列中还未被使用的数字 $j$,如果 $i$ 和 $j$ 满足题目要求,那么我们就可以将 $j$ 加入排列中,此时状态变为 $mask \mid 2^j$,其中 $|$ 表示按位或运算。由于 $j$ 已经被使用,因此我们需要递归计算 $dfs(mask \mid 2^j)$ 的值,并将其累加到 $dfs(mask)$ 上。
79+
80+
最终,我们可以得到 $dfs(0)$ 的值,即为答案。
81+
82+
时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(2^n)$。其中 $n$ 为排列的长度。
83+
84+
**方法二:状态压缩 + 动态规划**
85+
86+
我们可以将方法一中的记忆化搜索改写为动态规划的形式,定义 $f[mask]$ 表示当前排列的状态为 $mask$,且满足题目要求的排列的数量。初始时 $f[0]=1$,其余值均为 $0$。
87+
88+
我们在 $[0, 2^n)$ 的范围内枚举 $mask$,对于每个 $mask$,我们用 $i$ 表示当前最后一个加入排列的是第几个数字,然后我们枚举当前排列中最后一个加入的数字 $j$,如果 $i$ 和 $j$ 满足题目要求,那么状态 $f[mask]$ 就可以从状态 $f[mask \oplus 2^(j-1)]$ 转移而来,其中 $\oplus$ 表示按位异或运算。我们将所有转移得到的状态 $f[mask \oplus 2^(j-1)]$ 的值累加到 $f[mask]$ 上,即为 $f[mask]$ 的值。
89+
90+
最终,我们可以得到 $f[2^n - 1]$ 的值,即为答案。
91+
92+
时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(2^n)$。其中 $n$ 为排列的长度。
93+
94+
<!-- tabs:start -->
95+
96+
### **Python3**
97+
98+
<!-- 这里可写当前语言的特殊实现逻辑 -->
99+
100+
```python
101+
class Solution:
102+
def selfDivisiblePermutationCount(self, n: int) -> int:
103+
@cache
104+
def dfs(mask: int) -> int:
105+
i = mask.bit_count() + 1
106+
if i > n:
107+
return 1
108+
ans = 0
109+
for j in range(1, n + 1):
110+
if (mask >> j & 1) == 0 and (i % j == 0 or j % i == 0):
111+
ans += dfs(mask | 1 << j)
112+
return ans
113+
114+
return dfs(0)
115+
```
116+
117+
```python
118+
class Solution:
119+
def selfDivisiblePermutationCount(self, n: int) -> int:
120+
f = [0] * (1 << n)
121+
f[0] = 1
122+
for mask in range(1 << n):
123+
i = mask.bit_count()
124+
for j in range(1, n + 1):
125+
if (mask >> (j - 1) & 1) == 1 and (i % j == 0 or j % i == 0):
126+
f[mask] += f[mask ^ (1 << (j - 1))]
127+
return f[-1]
128+
```
129+
130+
### **Java**
131+
132+
<!-- 这里可写当前语言的特殊实现逻辑 -->
133+
134+
```java
135+
class Solution {
136+
private int n;
137+
private Integer[] f;
138+
139+
public int selfDivisiblePermutationCount(int n) {
140+
this.n = n;
141+
f = new Integer[1 << (n + 1)];
142+
return dfs(0);
143+
}
144+
145+
private int dfs(int mask) {
146+
if (f[mask] != null) {
147+
return f[mask];
148+
}
149+
int i = Integer.bitCount(mask) + 1;
150+
if (i > n) {
151+
return 1;
152+
}
153+
f[mask] = 0;
154+
for (int j = 1; j <= n; ++j) {
155+
if ((mask >> j & 1) == 0 && (i % j == 0 || j % i == 0)) {
156+
f[mask] += dfs(mask | 1 << j);
157+
}
158+
}
159+
return f[mask];
160+
}
161+
}
162+
```
163+
164+
```java
165+
class Solution {
166+
public int selfDivisiblePermutationCount(int n) {
167+
int[] f = new int[1 << n];
168+
f[0] = 1;
169+
for (int mask = 0; mask < 1 << n; ++mask) {
170+
int i = Integer.bitCount(mask);
171+
for (int j = 1; j <= n; ++j) {
172+
if (((mask >> (j - 1)) & 1) == 1 && (i % j == 0 || j % i == 0)) {
173+
f[mask] += f[mask ^ (1 << (j - 1))];
174+
}
175+
}
176+
}
177+
return f[(1 << n) - 1];
178+
}
179+
}
180+
```
181+
182+
### **C++**
183+
184+
```cpp
185+
class Solution {
186+
public:
187+
int selfDivisiblePermutationCount(int n) {
188+
int f[1 << (n + 1)];
189+
memset(f, -1, sizeof(f));
190+
function<int(int)> dfs = [&](int mask) {
191+
if (f[mask] != -1) {
192+
return f[mask];
193+
}
194+
int i = __builtin_popcount(mask) + 1;
195+
if (i > n) {
196+
return 1;
197+
}
198+
f[mask] = 0;
199+
for (int j = 1; j <= n; ++j) {
200+
if ((mask >> j & 1) == 0 && (i % j == 0 || j % i == 0)) {
201+
f[mask] += dfs(mask | 1 << j);
202+
}
203+
}
204+
return f[mask];
205+
};
206+
return dfs(0);
207+
}
208+
};
209+
```
210+
211+
```cpp
212+
class Solution {
213+
public:
214+
int selfDivisiblePermutationCount(int n) {
215+
int f[1 << n];
216+
memset(f, 0, sizeof(f));
217+
f[0] = 1;
218+
for (int mask = 0; mask < 1 << n; ++mask) {
219+
int i = __builtin_popcount(mask);
220+
for (int j = 1; j <= n; ++j) {
221+
if (((mask >> (j - 1)) & 1) == 1 && (i % j == 0 || j % i == 0)) {
222+
f[mask] += f[mask ^ (1 << (j - 1))];
223+
}
224+
}
225+
}
226+
return f[(1 << n) - 1];
227+
}
228+
};
229+
```
230+
231+
### **Go**
232+
233+
```go
234+
func selfDivisiblePermutationCount(n int) int {
235+
f := make([]int, 1<<(n+1))
236+
for i := range f {
237+
f[i] = -1
238+
}
239+
var dfs func(int) int
240+
dfs = func(mask int) int {
241+
if f[mask] != -1 {
242+
return f[mask]
243+
}
244+
i := bits.OnesCount(uint(mask)) + 1
245+
if i > n {
246+
return 1
247+
}
248+
f[mask] = 0
249+
for j := 1; j <= n; j++ {
250+
if mask>>j&1 == 0 && (i%j == 0 || j%i == 0) {
251+
f[mask] += dfs(mask | 1<<j)
252+
}
253+
}
254+
return f[mask]
255+
}
256+
return dfs(0)
257+
}
258+
```
259+
260+
```go
261+
func selfDivisiblePermutationCount(n int) int {
262+
f := make([]int, 1<<n)
263+
f[0] = 1
264+
for mask := 0; mask < 1<<n; mask++ {
265+
i := bits.OnesCount(uint(mask))
266+
for j := 1; j <= n; j++ {
267+
if mask>>(j-1)&1 == 1 && (i%j == 0 || j%i == 0) {
268+
f[mask] += f[mask^(1<<(j-1))]
269+
}
270+
}
271+
}
272+
return f[(1<<n)-1]
273+
}
274+
```
275+
276+
### **TypeScript**
277+
278+
```ts
279+
function selfDivisiblePermutationCount(n: number): number {
280+
const f: number[] = Array(1 << (n + 1)).fill(-1);
281+
const dfs = (mask: number): number => {
282+
if (f[mask] !== -1) {
283+
return f[mask];
284+
}
285+
const i = bitCount(mask) + 1;
286+
if (i > n) {
287+
return 1;
288+
}
289+
f[mask] = 0;
290+
for (let j = 1; j <= n; ++j) {
291+
if (((mask >> j) & 1) === 0 && (i % j === 0 || j % i === 0)) {
292+
f[mask] += dfs(mask | (1 << j));
293+
}
294+
}
295+
return f[mask];
296+
};
297+
return dfs(0);
298+
}
299+
300+
function bitCount(i: number): number {
301+
i = i - ((i >>> 1) & 0x55555555);
302+
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
303+
i = (i + (i >>> 4)) & 0x0f0f0f0f;
304+
i = i + (i >>> 8);
305+
i = i + (i >>> 16);
306+
return i & 0x3f;
307+
}
308+
```
309+
310+
```ts
311+
function selfDivisiblePermutationCount(n: number): number {
312+
const f: number[] = Array(1 << n).fill(0);
313+
f[0] = 1;
314+
for (let mask = 0; mask < 1 << n; ++mask) {
315+
const i = bitCount(mask);
316+
for (let j = 1; j <= n; ++j) {
317+
if ((mask >> (j - 1)) & 1 && (i % j === 0 || j % i === 0)) {
318+
f[mask] += f[mask ^ (1 << (j - 1))];
319+
}
320+
}
321+
}
322+
return f.at(-1)!;
323+
}
324+
325+
function bitCount(i: number): number {
326+
i = i - ((i >>> 1) & 0x55555555);
327+
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
328+
i = (i + (i >>> 4)) & 0x0f0f0f0f;
329+
i = i + (i >>> 8);
330+
i = i + (i >>> 16);
331+
return i & 0x3f;
332+
}
333+
```
334+
335+
### **...**
336+
337+
```
338+
339+
```
340+
341+
<!-- tabs:end -->

0 commit comments

Comments
 (0)