Beautiful Arrangement

medium array dp backtracking bitmask

Problem

Count permutations perm[1..n] such that for every i, perm[i] is divisible by i or i is divisible by perm[i].

Inputn = 4
Output8
Backtracking from position 1; or bitmask DP over chosen subset.

def count_arrangement(n):
    used = [False] * (n + 1)
    def back(pos):
        if pos > n: return 1
        s = 0
        for x in range(1, n + 1):
            if used[x] or (x % pos != 0 and pos % x != 0): continue
            used[x] = True
            s += back(pos + 1)
            used[x] = False
        return s
    return back(1)
function countArrangement(n) {
  const used = new Array(n + 1).fill(false);
  function back(pos) {
    if (pos > n) return 1;
    let s = 0;
    for (let x = 1; x <= n; x++) {
      if (used[x] || (x % pos !== 0 && pos % x !== 0)) continue;
      used[x] = true;
      s += back(pos + 1);
      used[x] = false;
    }
    return s;
  }
  return back(1);
}
class Solution {
    boolean[] used;
    int N;
    public int countArrangement(int n) {
        used = new boolean[n + 1]; N = n;
        return back(1);
    }
    int back(int pos) {
        if (pos > N) return 1;
        int s = 0;
        for (int x = 1; x <= N; x++) {
            if (used[x] || (x % pos != 0 && pos % x != 0)) continue;
            used[x] = true;
            s += back(pos + 1);
            used[x] = false;
        }
        return s;
    }
}
vector used;
int N;
int back(int pos) {
    if (pos > N) return 1;
    int s = 0;
    for (int x = 1; x <= N; x++) {
        if (used[x] || (x % pos != 0 && pos % x != 0)) continue;
        used[x] = true;
        s += back(pos + 1);
        used[x] = false;
    }
    return s;
}
int countArrangement(int n) { N = n; used.assign(n + 1, false); return back(1); }
Time: O(n!) Space: O(n)