LeetCode每日一题 526. 优美的排列

161 阅读1分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

526. 优美的排列

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

  1. i 位的数字能被 i 整除
  2. i 能被第 i 位上的数字整除

现在给定一个整数 N,请问可以构造多少个优美的排列?

示例1:

输入: 2
输出: 2
解释: 
第 1 个优美的排列是 [1, 2]:
  第 1 个位置(i=1)上的数字是11能被 ii=1)整除
  第 2 个位置(i=2)上的数字是22能被 ii=2)整除
第 2 个优美的排列是 [2, 1]:
  第 1 个位置(i=1)上的数字是22能被 ii=1)整除
  第 2 个位置(i=2)上的数字是1ii=2)能被 1 整除

说明:

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

方法一

看一眼数据范围,n不会超过15,那么可以放心大胆的使用面向用例编程大法

首先在测试用例中分别输入

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

接着编写代码 -_-

class Solution {
    public int countArrangement(int n) {
        int[] ans = new int[]{0,1,2,3,8,10,36,41,132,250,700,750,4010,4237,10680,24679};
        return ans[n];
    }
}

方法二

递归加回溯:看一眼数据范围,n不会超过15,那么可以放心大胆的使用递归;

  • 递归出口:当递归到第u个数时,有u>n,说明1~n已经全部被用完且这条路径符合题意,答案加1,并返回;
  • 递归进入下一层的条件:当前这个数,在之前没有被使用,且符合题目中给的条件,即,要么这第i个位置上的数能被i整除,要么这个第i个位置上的数,能够把i给整除;
class Solution {
    int res = 0, n;
    boolean[] st;
    public int countArrangement(int _n) {
        n = _n;
        st = new boolean[n + 1];
        dfs(1);
        return res;
    }
​
    void dfs(int u) {
        if (u > n) {
            res ++;
            return;
        }
​
        for (int i = 1; i <= n; i ++ ) {
            if (!st[i] && (u % i == 0 || i % u == 0)) {
                st[i] = true;  
                dfs(u + 1);
                st[i] = false;
            }
        }
        return ;
    }
}