开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情
题目:LeetCode
假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组 perm(下标从 1 开始),只要满足下述条件 之一 ,该数组就是一个 优美的排列 :
perm[i]能够被i整除i能够被perm[i]整除
给你一个整数 n ,返回可以构造的 优美排列 的 数量 。
示例 1:
输入: n = 2
输出: 2
解释:
第 1 个优美的排列是 [1,2]:
- perm[1] = 1 能被 i = 1 整除
- perm[2] = 2 能被 i = 2 整除
第 2 个优美的排列是 [2,1]:
- perm[1] = 2 能被 i = 1 整除
- i = 2 能被 perm[2] = 1 整除
示例 2:
输入: n = 1
输出: 1
提示:
1 <= n <= 15
解题思路
根据题意本题思路比较明晰,直接求出n的所有排列,并查看排列是否满足题目给出的条件,不满足则剪枝,满足则继续往下遍历,直到遍历的轨迹大小等于n
写出求数的全排序:
- 先定义dfs函数,入参肯定有数的大小n, 集合track代表运行轨迹
- 首先是回溯的退出条件: 当track的数量等于n时表明可以组成排序,res++
- 接着从1到n遍历所有的数字num
- 因为全排列不能包含重复数字,当track包含数组num时直接跳过
- 将num加入track中,做选择
- 递归遍历
- 最后将track的末尾删除,撤销选择
代码实现
public static int count = 0;
public static int countArrangement(int n) {
List < Integer > track = new ArrayList < > ();
dfs(n, track);
return count;
}
public static void dfs(int n, List < Integer > track) {
if (track.size() == n) {
count++;
return;
}
for (int i = 1; i <= n; i++) {
if (track.contains(i)) {
continue;
}
track.add(i);
if (i % track.size() == 0 || track.size() % i == 0) {
dfs(n, track);
}
track.remove(track.size() - 1);
}
}
运行结果
复杂度分析
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN) 一起分享知识, Keep Learning!