Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is constructed by these N numbers successfully if one of the following is true for the ith position (1 <= i <= N) in this array:
- The number at the ith position is divisible by i.
- i is divisible by the number at the ith position.
Now given N, how many beautiful arrangements can you construct?
Example 1:
Input: 2
Output: 2
Explanation:
The first beautiful arrangement is [1, 2]:
Number at the 1st position (i=1) is 1, and 1 is divisible by i (i=1).
Number at the 2nd position (i=2) is 2, and 2 is divisible by i (i=2).
The second beautiful arrangement is [2, 1]:
Number at the 1st position (i=1) is 2, and 2 is divisible by i (i=1).
Number at the 2nd position (i=2) is 1, and i (i=2) is divisible by 1.
Note:
N is a positive integer and will not exceed 15.
算法解析:利用回溯法遍历所有可能的结果,类似于深度优先搜索。Python版如果套用C语言的套路,会在计算n=15的时候超时,所以用了别人写了一个动态规划的算法。
C语言版
void solve(int* visited, int t, int n)
{
int i;
if(t > n)
visited[0]++;
for(i = 1; i <= n; i++)
{
if(!visited[i] && (t % i == 0 || i % t == 0))
{
visited[i] = 1;
solve(visited, t + 1, n);
visited[i] = 0;
}
}
}
int countArrangement(int N) {
int t = 1;
int visited[16] = {0};
solve(visited, t, N);
return visited[0];
}
Python版
cache = {}
class Solution(object):
def countArrangement(self, N):
def helper(i, X):
if i == 1:
return 1
key = (i, X)
if key in cache:
return cache[key]
total = 0
for j in xrange(len(X)):
if X[j] % i == 0 or i % X[j] == 0:
total += helper(i - 1, X[:j] + X[j + 1:])
cache[key] = total
return total
return helper(N, tuple(range(1, N + 1)))