1.基于排列组合的DFS / 基于图的DFS
leetcode 526 优美的排列
假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组 perm(下标从 1 开始),只要满足下述条件 之一 ,该数组就是一个 优美的排列 :
- perm[i] 能够被 i 整除
- i 能够被 perm[i] 整除
给你一个整数 n ,返回可以构造的 优美排列 的 数量 。
class Solution {
List<Integer>[] match;
boolean[] visited;
int num;
public int countArrangement(int n) {
visited = new boolean[n + 1];
match = new List[n + 1];
// 初始化match集合数组
for (int i = 0; i <= n; i++) {
match[i] = new ArrayList<Integer>();
}
// 把满足条件的ij放入match集合数组中
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i % j == 0 || j % i == 0) {
match[i].add(j);
}
}
}
// 开始dfs深潜
dfs(1, n);
return num;
}
public void dfs(int index, int n){
// 当index到临界值时,结束dfs
if(index == n + 1){
num++;
return;
}
// 遍历每一个match[index]]集合中的数字,进行组合
// 从match[0]集合开始,一层一层的进行组合
for (int x : match[index]) {
// 如果集合中的x没有访问过
if (!visited[x]) {
// 使用后标记
visited[x] = true;
// 进入下一层DFS,index + 1,开始从match[index + 1]进行选择排列
dfs(index + 1, n);
// 每轮之后进行重置
visited[x] = false;
}
}
}
}