Special Permutations - DP w/ Bitmasks [JS]

Description 

Solution: DP w/ Bitmasks

Memoize each dp(mask, prevIndex), where

  • mask = bitmask which indicates which numbers we have used so far
  • prevIndex = index of the previous number in the permutation

For each dp(mask, prevIndex), go through each number and try each unused number that is valid for the current sequence.
Count the total number of ways.

Time Complexity: O(2^n * n^2)
Space Complexity: O(2^n * n)

var specialPerm = function(nums) {
  let n = nums.length, fullMask = (1 << n) - 1;
  let memo = Array(1 << n).fill(0).map(() => Array(n).fill(-1)), MOD = 10 ** 9 + 7, res = 0;
  for (let i = 0; i < n; i++) {
    res = (res + dp(1 << i, i)) % MOD;
  }
  return res;
  
  function dp(mask, prevIndex) {
    if (mask === fullMask) return 1;
    if (memo[mask][prevIndex] !== -1) return memo[mask][prevIndex];

    let ans = 0;
    for (let i = 0; i < n; i++) {
      if ((mask >> i) & 1) continue; 
      if ((nums[i] % nums[prevIndex] === 0) || (nums[prevIndex] % nums[i] === 0)) {
        let newMask = mask | (1 << i);
        ans = (ans + dp(newMask, i)) % MOD;
      }
    }
    return memo[mask][prevIndex] = ans;
  }  
};

Comments

Popular posts from this blog

Beautiful Towers II - Monotonic Increasing Stack [JS]

Minimum Number of Operations to Sort a Binary Tree by Level - BFS & Cycle Counting Explained [JS]

Maximum Sum of Distinct Subarrays With Length K - Sliding Window w/ Two Pointers & Set [JS]

Maximum Score After Applying Operations on a Tree - DFS [JS]

Divide Nodes Into the Maximum Number of Groups - Union Find & BFS [JS]