題目來源:力扣
題目介紹:
假設有從 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,則表示當前構建數組爲優美排列,返回1.如果當前數組的所有可選子集均無法稱爲優美排列的元素,則返回0.
class Solution {
//使用一個長度爲N的boolean數組紀錄當前第i個數值是否被使用
private int dfs(boolean [] used, int n){
if(n == used.length) //如果當前構建了數組,返回1
return 1;
int res = 0;
for(int i = 1; i < used.length; i++){
if(!used[i]){
if(i % n == 0 || n % i == 0){//如果當前值可以構建
used[i] = true;
res += dfs(used, n+1);
used[i] = false;
}
}
}
return res;
}
public int countArrangement(int N) {
boolean[] used = new boolean[N+1];
return dfs(used, 1);
}
}