1. 程式人生 > >leetcode526_優美的排列--回溯法

leetcode526_優美的排列--回溯法

假設有從 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);   //子遞迴結束   交換回來
        }
    }