图论解法:哈密顿通路问题 Leetcode 2741. 特别的排列

描述

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

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

请你返回特别排列的总数目,由于答案可能很大,请将它对 10^9 + 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] <= 10^9

思路

可以用图中的边表示两个数(结点)能满足题目描述的排列关系。因此问题转化为求出无向图中不重复经过所有节点的路径。

这个问题其实就是哈密顿通路问题。

一开始本人建图后,用dfs搜,超时了。然后改成了记忆化搜索。
进一步可改进地,可以用一个mask来表示搜索的状态(表示visited_map)(题目的2 <= nums.length <= 14其实就有暗示,结点数量有限)

代码

本人写的记忆化搜索

class Solution:
    def specialPerm(self, nums: List[int]) -> int:
        n = len(nums)
        self.adj_map = {
   
   }
        for i,num1 in enumerate(nums):
            for j in range(i+1,n):
                num2 = nums[j]
                if(num1 % num2 != 0 and num2 % num1 != 0)</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值