Welcome to Subscribe On Youtube
526. Beautiful Arrangement
Description
Suppose you have n integers labeled 1 through n. A permutation of those n integers perm (1-indexed) is considered a beautiful arrangement if for every i (1 <= i <= n), either of the following is true:
perm[i]is divisible byi.iis divisible byperm[i].
Given an integer n, return the number of the beautiful arrangements that you can construct.
Example 1:
Input: n = 2
Output: 2
Explanation:
The first beautiful arrangement is [1,2]:
- perm[1] = 1 is divisible by i = 1
- perm[2] = 2 is divisible by i = 2
The second beautiful arrangement is [2,1]:
- perm[1] = 2 is divisible by i = 1
- i = 2 is divisible by perm[2] = 1
Example 2:
Input: n = 1 Output: 1
Constraints:
1 <= n <= 15
Solutions
Solution 1: Depth-First Search + Hash Table
This implementation uses depth-first search, followed by hash table. It traverses the relevant values and updates its state as each value is processed. A keyed container records values that must be found or updated efficiently. After all required states have been considered, the maintained result is returned.
Solution 2
This implementation uses dynamic programming, followed by bit manipulation. It traverses the relevant values and updates its state as each value is processed. After all required states have been considered, the maintained result is returned.
-
class Solution { public int countArrangement(int N) { int maxn = 1 << N; int[] f = new int[maxn]; f[0] = 1; for (int i = 0; i < maxn; ++i) { int s = 1; for (int j = 0; j < N; ++j) { s += (i >> j) & 1; } for (int j = 1; j <= N; ++j) { if (((i >> (j - 1) & 1) == 0) && (s % j == 0 || j % s == 0)) { f[i | (1 << (j - 1))] += f[i]; } } } return f[maxn - 1]; } } // Solution 2 class Solution { public int countArrangement(int N) { int maxn = 1 << N; int[] f = new int[maxn]; f[0] = 1; for (int i = 0; i < maxn; ++i) { int s = 1; for (int j = 0; j < N; ++j) { s += (i >> j) & 1; } for (int j = 1; j <= N; ++j) { if (((i >> (j - 1) & 1) == 0) && (s % j == 0 || j % s == 0)) { f[i | (1 << (j - 1))] += f[i]; } } } return f[maxn - 1]; } } -
class Solution { public: int n; int ans; vector<bool> vis; unordered_map<int, vector<int>> match; int countArrangement(int n) { this->n = n; this->ans = 0; vis.resize(n + 1); for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) if (i % j == 0 || j % i == 0) match[i].push_back(j); dfs(1); return ans; } void dfs(int i) { if (i == n + 1) { ++ans; return; } for (int j : match[i]) { if (!vis[j]) { vis[j] = true; dfs(i + 1); vis[j] = false; } } } }; -
class Solution: def countArrangement(self, n: int) -> int: def dfs(i): nonlocal ans, n if i == n + 1: ans += 1 return for j in match[i]: if not vis[j]: vis[j] = True dfs(i + 1) vis[j] = False ans = 0 vis = [False] * (n + 1) match = defaultdict(list) for i in range(1, n + 1): for j in range(1, n + 1): if j % i == 0 or i % j == 0: match[i].append(j) dfs(1) return ans -
func countArrangement(n int) int { ans := 0 match := make(map[int][]int) for i := 1; i <= n; i++ { for j := 1; j <= n; j++ { if i%j == 0 || j%i == 0 { match[i] = append(match[i], j) } } } vis := make([]bool, n+1) var dfs func(i int) dfs = func(i int) { if i == n+1 { ans++ return } for _, j := range match[i] { if !vis[j] { vis[j] = true dfs(i + 1) vis[j] = false } } } dfs(1) return ans } -
function countArrangement(n: number): number { const vis = new Array(n + 1).fill(0); const match = Array.from({ length: n + 1 }, () => []); for (let i = 1; i <= n; i++) { for (let j = 1; j <= n; j++) { if (i % j === 0 || j % i === 0) { match[i].push(j); } } } let res = 0; const dfs = (i: number, n: number) => { if (i === n + 1) { res++; return; } for (const j of match[i]) { if (!vis[j]) { vis[j] = true; dfs(i + 1, n); vis[j] = false; } } }; dfs(1, n); return res; } -
impl Solution { fn dfs(i: usize, n: usize, mat: &Vec<Vec<usize>>, vis: &mut Vec<bool>, res: &mut i32) { if i == n + 1 { *res += 1; return; } for &j in mat[i].iter() { if !vis[j] { vis[j] = true; Self::dfs(i + 1, n, mat, vis, res); vis[j] = false; } } } pub fn count_arrangement(n: i32) -> i32 { let n = n as usize; let mut vis = vec![false; n + 1]; let mut mat = vec![Vec::new(); n + 1]; for i in 1..=n { for j in 1..=n { if i % j == 0 || j % i == 0 { mat[i].push(j); } } } let mut res = 0; Self::dfs(1, n, &mat, &mut vis, &mut res); res } }