2741. 特别的排列 Medium

给你一个下标从 0 开始的整数数组 nums ,它包含 n互不相同 的正整数。如果 nums 的一个排列满足以下条件,我们称它是一个特别的排列:

·对于 0 <= i < n - 1 的下标 i ,要么 nums[i] % nums[i+1] == 0 ,要么 nums[i+1] % nums[i] == 0

请你返回特别排列的总数目,由于答案可能很大,请将它对109 + 7 取余 后返回。

示例 1:

复制代码
输入:nums = [2,3,6]
输出:2
解释:[3,6,2] 和 [2,6,3] 是 nums 两个特别的排列。

示例 2:

复制代码
输入:nums = [1,4,3]
输出:2
解释:[3,1,4] 和 [4,1,3] 是 nums 两个特别的排列。

提示:

·2 <= nums.length <= 14

·1 <= nums[i] <= 109

题目大意:在只有可整除的数字能相邻的情况下计算所有合法排列的数量。

分析:

(1)由于可整除的数字可以相邻,因此可整除的两个数之间可以视为有一条无向边,用图的思想处理本题,将每个数字视为一个结点。分别从数组中的每个结点开始进行一次深度优先遍历,计算可以连接所有结点的路径的个数sum,得到的sum即为所求的合法排列的数量;

(2)由于长度为N的数组有N!种排列,用枚举的方式搜索会超时,因此采用记忆化搜索加速计算。设当前遍历的结点为i,当前的状态为flag,状态flag表示已遍历的结点和未遍历的结点,如flag=0b011001时表示第2、3、6个结点已被遍历,而第1、4、5个结点还没有遍历。因为在相同状态(flag)下遍历i结点,返回的合法排列数量是相同的,所以建立二维数组dp,其中dp[i][flag]表示在状态flag的情况下遍历i结点可获得的合法排列数量,以此记录已遍历过的情况,加速深度优先搜索。

cpp 复制代码
class Solution {
public:
    int specialPerm(vector<int>& nums) {
        int N=nums.size(),flag=(1<<N)-1,ans=0;
        vector<vector<int>> dp(N,vector<int>(1<<N,-1));
        function<int(int)> dfs=[&](int root){
            if(dp[root][flag]!=-1) return dp[root][flag];
            int sum=0;
            for(int i=0,f=1;i<N;++i,f<<=1){
                if(root!=i&&(flag&f)&&!(nums[i]%nums[root]&&nums[root]%nums[i])){
                    flag^=f;
                    sum=(sum+dfs(i))%1000000007;
                    flag^=f;
                }
            }
            return dp[root][flag]=sum;
        };
        for(int i=0;i<N;++i) dp[i][0]=1;
        for(int i=0,f=1;i<N;++i,f<<=1){
            flag^=f;
            ans=(ans+dfs(i))%1000000007;
            flag^=f;
        }
        return ans;
    }
};
相关推荐
.千余7 小时前
【C++】C++继承入门(下):友元、静态成员与菱形继承的底层逻辑
开发语言·c++·笔记·学习·其他
初中就开始混世的大魔王8 小时前
6 Fast DDS-传输层
开发语言·c++·中间件·信息与通信
退休倒计时8 小时前
【每日一题】LeetCode 142. 环形链表 II TypeScript
算法·leetcode·链表·typescript
popcorn_min8 小时前
Digits 手写数字识别:随机森林多分类 + 像素级特征热力图
算法·随机森林·分类
liulilittle9 小时前
拥塞控制:排水终止的两种决策:OR 与 AND
网络·tcp/ip·计算机网络·算法·信息与通信·tcp·通信
weixin_307779139 小时前
从脚本执行到智能体协作:AI辅助测试能力的范式重构
运维·开发语言·人工智能·算法·测试用例
量化君也9 小时前
从回测到全自动实盘交易,全天候策略需要经历哪些改造?
大数据·人工智能·python·算法·金融
代码中介商10 小时前
C++ 智能指针完全指南(三):weak_ptr 与循环引用
开发语言·c++
fox_lht10 小时前
第十五章 函数式语言:迭代器和闭包
开发语言·后端·学习·算法·rust
BestOrNothing_201510 小时前
ROS2 C++ 小车控制完整实战(二):自定义 msg 消息发布与订阅保姆级教程
c++·ros2·subscriber·publisher·msg·topic通信·自定义接口