Leetcode 526. 优美的排列 (回溯)

42 篇文章 0 订阅

假设有从 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 整除

【思路】:
与全排列思路基本一致,最后加个判断即可。

注:如果每次都是搜到最后才判断,则会超时!
所以我们用一个剪枝的手法。

因为要想整个数组都是优美排列,必须保证,其子数组也是。
因此我们没有必要每次在最后时刻再判断,如果一开始就不是优美排列,就没有必要搜索下去了。

事实证明,这个剪枝策略带来的优化效果是巨大的!


【代码】:

/**
 * @param {number} n
 * @return {number}
 */

var isBeautiful = function(perm){
    let bool = true;
    for(let i =1;i < perm.length;i++){
        if(perm[i] % i == 0 || i % perm[i] == 0)    continue;
        bool = false;
        break;
    }
    return bool;
}

var dfs = function(k, n, vis, path, res, bool){
    //关键剪枝,不用到最后一步再判断!
    if(!isBeautiful(path)) return ;
    if(k > n){
        //judge
        if(isBeautiful(path)){
            bool.cnt++;
        }
        return ;
    }

    for(let i = 1;i <= n;i++){
        if(vis[i] == 1) continue;
        vis[i] = 1;
        path.push(i);
        dfs(k + 1, n, vis, path, res,bool);
        path.pop();
        vis[i] = 0;
    }
}

var countArrangement = function(n) {
    var vis = new Array(n + 1).fill(0);
    var res = [];
    var bool = {cnt:0};
    dfs(1, n, vis, [-1], res, bool);
    return bool.cnt;
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值