funcfindValueOfPartition(nums []int)int { sort.Ints(nums) res := math.MaxInt for i := 1; i < len(nums); i++ { res = min(res, nums[i]-nums[i-1]) } return res }
funcmin(a, b int)int { if a < b { return a }; return b }
2741. 特别的排列
解题思路(回溯):
使用回溯的思路,定义 dfs(track,j),其中 track 为数组,存储已选择下标,j 表示上一次选择的下标。同时使用全局 used 标记是否选择过。
当数组 tarck 长度等于 nums 的长度时,表示找到一个特别的排列,直接返回。
枚举当前要选择的下标 k, 如果 nums[k] 与 nums[j] 满足整除的要求,将 k 加入 track 数组中并标记 used 为已使用,并进行回溯,结束回溯从 track 中取出 k 并重置 used 中 k 的状态
for k, x := range nums { if !used[k] && (nums[j]%x != 0 || x%nums[j] != 0) { track = append(track, x) used[k] = true res = (res + dfs(track, k)) % mod used[k] = false track = track[:len(track)-1] } } return res } var res int for i, num := range nums { used[i] = true res = (res + dfs([]int{num}, i)) % mod used[i] = false } return res }
funcspecialPerm(nums []int)int { const mod int = 1e9 + 7 n := len(nums) m := 1 << n - 1 memo := make([][]int, m) for i := range memo { memo[i] = make([]int, n) for j := range memo[i] { memo[i][j] = -1 } }
var dfs func(int, int)int dfs = func(i int, j int) (res int) { if i == 0 { return1 }
if memo[i][j] != -1 { return memo[i][j] }
for k, x := range nums { if i>>k&1 == 1 && (nums[j]%x == 0 || x%nums[j] == 0) { res = (res + dfs(i^(1<<k), k)) % mod } } memo[i][j] = res return res } var res int for i := range nums { res = (res + dfs(m^(1<<i), i)) % mod } return res }
funcspecialPerm(nums []int)int { const mod int = 1e9 + 7 n := len(nums) m := 1<<n - 1 dp := make([][]int, m) dp[0] = make([]int, n) for i := range dp[0] { dp[0][i] = 1 }
for i := 1; i < m; i++ { dp[i] = make([]int, n) for j, x := range nums { for k, y := range nums { if i>>k&1 == 1 && (y%x == 0 || x%y == 0) { dp[i][j] = (dp[i][j] + dp[i^(1<<k)][k]) % mod } } } }
var res int for i := range nums { res = (res + dp[m^(1<<i)][i]) % mod } return res }