假设有从 1 到 N 的 N 个整数,如果从这 N 个数字中成功构造出一个数组,使得数组的第 i 位 (1 <= i <= N) 满足如下两个条件中的一个,我们就称这个数组为一个优美的排列。条件:

第 i 位的数字能被 i 整除
i 能被第 i 位上的数字整除
现在给定一个整数 N,请问可以构造多少个优美的排列?

示例1:

输入: 2
输出: 2
解释: 

第 1 个优美的排列是 [1, 2]:
  第 1 个位置(i=1)上的数字是1,1能被 i(i=1)整除
  第 2 个位置(i=2)上的数字是2,2能被 i(i=2)整除

第 2 个优美的排列是 [2, 1]:
  第 1 个位置(i=1)上的数字是2,2能被 i(i=1)整除
  第 2 个位置(i=2)上的数字是1,i(i=2)能被 1 整除
说明:

N 是一个正整数,并且不会超过15。

思路:

类似全排列的解法  就是看排列的结果是否满足题目意思  进行回溯法递归  先确定第一个位置  对之后位置进行递归  

    // 类似全排列的解法 回溯法子  相當於看排列的方式是否滿足條件
    int count = 0;
    public int countArrangement(int N) {
        if (N == 0) return 0;
        int[] arr = new int[N+1];
        for (int i = 0; i <= N; i++) arr[i] = i;
        getBeautifyCount(arr,1, N);  //1到n的位置
        return count;
    }
    private void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    private void getBeautifyCount(int[] arr, int start, int n) {
        if (start > n) {
            count++;
            return;
        }
        //每次確定當前位置  後面的位置遞歸
        for (int i = start; i <= n; i++) { 
            swap(arr, start, i);   //交換  直到子递归结束
            if (arr[start] % start == 0 || start % arr[start] == 0) getBeautifyCount(arr, start+1,n);
            swap(arr,i, start);   //子递归结束   交換回來
        }
    }