Special Permutations
MedPrompt
You are given a 0-indexed integer array nums containing n distinct positive integers. A permutation of nums is called special if:
- For all indexes
0 <= i < n - 1, eithernums[i] % nums[i+1] == 0ornums[i+1] % nums[i] == 0.
Return the total number of special permutations. As the answer could be large, return it modulo 109 + 7.
Example 1:
Input: nums = [2,3,6]
Output: 2
Explanation: [3,6,2] and [2,6,3] are the two special permutations of nums.Example 2:
Input: nums = [1,4,3]
Output: 2
Explanation: [3,1,4] and [4,1,3] are the two special permutations of nums.
Constraints:
2 <= nums.length <= 141 <= nums[i] <= 109
Approaches
3 approaches with complexity analysis and trade-offs.
This approach involves generating every possible arrangement (permutation) of the nums array. For each generated permutation, it performs a check to see if it satisfies the "special" condition. If it does, a counter is incremented. This method is the most straightforward to conceptualize but is computationally very expensive.
Algorithm
- Initialize a counter
countto 0. - Create a recursive helper function,
generatePermutations(nums, current_permutation, used_flags), to generate all permutations ofnums. - The function works as follows:
- Base Case: If the
current_permutationhasnelements, it's a complete permutation. Check if it's a special permutation using a helper functionisSpecial(). - If it is special, increment the
count(with modulo arithmetic). - Recursive Step: Iterate through each number in the original
numsarray. If a number hasn't been used, mark it as used, add it tocurrent_permutation, and make a recursive call. After the call returns, backtrack by removing the number and unmarking it.
- Base Case: If the
- The
isSpecial(permutation)helper function iterates fromi = 0ton-2and checks ifperm[i] % perm[i+1] == 0orperm[i+1] % perm[i] == 0for all adjacent pairs. If any pair fails this condition, it returnsfalse. - Start the process by calling
generatePermutationswith an empty permutation. - Return the final
count.
Walkthrough
The core idea is to explore all n! permutations of the input array. We can use a recursive helper function to build these permutations. The function maintains a list for the current permutation being built and a boolean array to keep track of which numbers from the original array have been used.
Once a full permutation of length n is formed, we validate it. The validation involves iterating through the permutation from the first to the second-to-last element and checking the divisibility condition for each adjacent pair (nums[i] and nums[i+1]). If all pairs in the permutation satisfy the condition, we increment our total count of special permutations. Since the answer can be large, the count is maintained modulo 10^9 + 7.
class Solution { long count = 0; int MOD = 1_000_000_007; public int specialPerm(int[] nums) { List<Integer> p = new ArrayList<>(); boolean[] used = new boolean[nums.length]; generatePermutations(nums, p, used); return (int) count; } private void generatePermutations(int[] nums, List<Integer> p, boolean[] used) { if (p.size() == nums.length) { if (isSpecial(p)) { count = (count + 1) % MOD; } return; } for (int i = 0; i < nums.length; i++) { if (!used[i]) { used[i] = true; p.add(nums[i]); generatePermutations(nums, p, used); p.remove(p.size() - 1); // Backtrack used[i] = false; } } } private boolean isSpecial(List<Integer> p) { for (int i = 0; i < p.size() - 1; i++) { if (p.get(i) % p.get(i + 1) != 0 && p.get(i + 1) % p.get(i) != 0) { return false; } } return true; }}Complexity
Time
O(n! * n) - There are `n!` possible permutations to generate. For each permutation, we take O(n) time to check if it's special. This makes the approach infeasible for `n > 10`.
Space
O(n) - The space is dominated by the recursion stack depth and the list used to store the current permutation, both of which can go up to size `n`.
Trade-offs
Pros
Simple to understand and implement.
Correctly solves the problem for very small values of
n.
Cons
Extremely inefficient due to its factorial time complexity.
Will result in a 'Time Limit Exceeded' error on platforms like LeetCode for constraints like n=14.
Solutions
Solution
class Solution {public int specialPerm(int[] nums) { final int mod = (int)1 e9 + 7; int n = nums.length; int m = 1 << n; int[][] f = new int[m][n]; for (int i = 1; i < m; ++i) { for (int j = 0; j < n; ++j) { if ((i >> j & 1) == 1) { int ii = i ^ (1 << j); if (ii == 0) { f[i][j] = 1; continue; } for (int k = 0; k < n; ++k) { if (nums[j] % nums[k] == 0 || nums[k] % nums[j] == 0) { f[i][j] = (f[i][j] + f[ii][k]) % mod; } } } } } int ans = 0; for (int x : f[m - 1]) { ans = (ans + x) % mod; } return ans; }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.