问题:
难度:medium
说明:
给一个数字 N,然后返回可以 1 ~ N 以内 从 数组索引 1 开始,可以组成多少个完美数组,其中:
完美数组每一个元素符合: arr[i] 可以被 i 整除,或者 i 可以被 arr[i] 整除。
题目连接:https://leetcode.com/problems/beautiful-arrangement/
输入范围:
1 <= n <= 15
输入案例:
Example 1:
Input: n = 2
Output: 2
Explanation:
The first beautiful arrangement is [1,2]:
- perm[1] = 1 is divisible by i = 1
- perm[2] = 2 is divisible by i = 2
The second beautiful arrangement is [2,1]:
- perm[1] = 2 is divisible by i = 1
- i = 2 is divisible by perm[2] = 1
Example 2:
Input: n = 1
Output: 1
我的代码:
一个暴力(全排列)就解决,如果快点就是写写数学公式,不过还有像打表这种不讲武德的东西,毕竟 N 是 15 以内。
Java:
class Solution {
int count = 0;
public int countArrangement(int n) {
recurtion(n + 1, new boolean[n + 1], 1, 0);
return count;
}
public void recurtion(int n, boolean[] visited, int index, int cur) {
if(index == n) {
count ++;
return;
}
for(int i = 1;i < n;i ++) {
if(i == cur) continue;
if((i % index == 0 || index % i == 0) && !visited[i]) {
visited[i] = true;
recurtion(n, visited, index + 1, i);
visited[i] = false;
}
}
}
}
Java 打表:
class Solution {
private static int[] map = new int[]{1, 2, 3, 8, 10, 36, 41, 132, 250, 700, 750, 4010, 4237, 10680, 24679};
public int countArrangement(int n) {
return map[n - 1];
}
}
C++:
class Solution {
public:
int count = 0;
int countArrangement(int n) {
short *visited = new short[n + 1];
recurtion(n + 1, visited, 1, 0);
return count;
}
void recurtion(int len, short *visited, int index, int cur) {
if (index == len) {
count++; return;
}
for (int i = 1; i < len; i++) {
if (i == cur) continue;
if ((i % index == 0 || index % i == 0) && visited[i]) {
visited[i] = 0;
recurtion(len, visited, index + 1, i);
visited[i] = 1;
}
}
}
};
C++就不打表了