Skip to main content

Beautiful Arrangement - Solution & Explanation

MediumArrayDynamic ProgrammingBacktrackingBit Manipulation15 min readAsked at: Amazon, Microsoft, Visa +3
Practice this problem

Problem Statement

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 by i.
  • i is divisible by perm[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

Approach Overview

Problem Overview: Given an integer n, count how many permutations of numbers 1..n form a beautiful arrangement. A permutation is valid if for every position i, either perm[i] % i == 0 or i % perm[i] == 0. The goal is to explore permutations efficiently while enforcing this divisibility constraint.

Approach 1: Backtracking with Pruning (Time: O(n!), Space: O(n))

This approach builds the permutation one position at a time using backtracking. Start at position 1 and try placing every unused number from 1..n. Before placing a number x at position i, check the constraint x % i == 0 or i % x == 0. If the condition fails, skip immediately. A boolean array or bit mask tracks which numbers are already used. The recursion proceeds until position n, where a valid arrangement is counted.

The key optimization is pruning invalid placements early. Instead of generating all n! permutations, the algorithm only explores candidates that satisfy the divisibility rule. For small constraints (the problem limits n ≤ 15), this dramatically reduces the search space. This solution is simple to implement and performs well because many permutations are rejected early.

Approach 2: Dynamic Programming with Bitmasking (Time: O(n * 2^n), Space: O(2^n))

This method replaces recursion with dynamic programming and represents chosen numbers using a bitmask. Each DP state stores the number of valid arrangements for a specific mask of used numbers. The number of set bits in the mask determines the current position in the permutation.

For each mask, try placing a number x that has not been used yet. If it satisfies the divisibility rule for the next position, transition to a new mask with the corresponding bit set. Memoization ensures each mask is computed only once. Since there are 2^n masks and up to n transitions per state, the complexity becomes O(n * 2^n).

This approach is more structured than pure recursion and avoids repeated exploration of identical states. Bitmask DP is common for permutation counting problems where n ≤ 20. It also demonstrates strong understanding of state compression techniques used in many advanced interview problems.

Recommended for interviews: Backtracking with pruning is usually the expected solution because it directly models permutation generation and clearly shows constraint-based pruning. It demonstrates control over recursion and search space reduction. The bitmask DP approach is a strong follow-up optimization that highlights knowledge of state compression and dynamic programming, which can impress interviewers when discussing scalability.

Approach 1: Backtracking Approach

The idea is to generate permutations of the numbers from 1 to n and check if each permutation is a beautiful arrangement. This can be efficiently done using backtracking. While generating permutations, we can directly test the divisibility conditions to ensure they form a beautiful arrangement.

This solution uses bitmasking to mark the numbers that have been used. It recursively checks each position with available numbers. If a number can be placed at a position according to the rules, it tries to place the next number. If a full beautiful arrangement is achieved, it counts it.

Code

Python

C

C++

Java

C#

JavaScript

Complexity

Time Complexity: O(k), where k are the valid permutations (worst-case roughly n!).
Space Complexity: O(n) due to the recursion stack.

Try this approach in the editor →

Approach 2: Dynamic Programming Approach with Bitmasking

This approach involves using dynamic programming (DP) with bitmasking to efficiently count beautiful arrangements. By representing the set of visited numbers as a bitmask and using memoization, we can avoid redundant calculations.

This Python solution uses a top-down dynamic programming approach with memoization. The function dfs uses a bitmask to denote which integers have been placed, and iteratively places integers satisfying the beautiful arrangement condition.

Code

Python

C

C++

Java

C#

JavaScript

Complexity

Time Complexity: O(n * 2^n) due to bitmask permutations.
Space Complexity: O(2^n) for the DP cache plus recursion stack.

Try this approach in the editor →

Approach 3: Default Approach

Code

Python

Java

C++

Go

TypeScript

Rust

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
Backtracking Approach

Time Complexity: O(k), where k are the valid permutations (worst-case roughly n!).
Space Complexity: O(n) due to the recursion stack.

Dynamic Programming Approach with Bitmasking

Time Complexity: O(n * 2^n) due to bitmask permutations.
Space Complexity: O(2^n) for the DP cache plus recursion stack.

Default Approach

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Backtracking with PruningO(n!)O(n)Best for interview explanations and small n (≤15). Easy to implement and prunes invalid permutations early.
Dynamic Programming with BitmaskO(n * 2^n)O(2^n)When you want a more optimized state-based approach and to avoid recomputing identical permutation states.

Video Solution

Beautiful Arrangement | LeetCode 526 | C++, Java, PythonKnowledge Center15,558 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Beautiful Arrangement easy or hard?
Beautiful Arrangement is classified as a medium difficulty problem. The core idea—checking divisibility while building permutations—is straightforward, but recognizing pruning opportunities or implementing the bitmask DP optimization requires stronger algorithmic thinking.
How to solve Beautiful Arrangement in O(n * 2^n)?
Use dynamic programming with bitmasking. Represent which numbers are used with a bitmask and let the number of set bits determine the current position. For each mask, try adding an unused number that satisfies the divisibility condition. Memoizing results for every mask ensures each state is computed once, giving O(n * 2^n) time complexity.
What is the best approach for Beautiful Arrangement?
Backtracking with pruning is the most common approach. It builds the permutation position by position and only places numbers that satisfy the divisibility rule with the current index. Because many permutations are rejected early, the practical runtime is much faster than generating all n! permutations. For n ≤ 15, this approach performs well and is easy to explain in interviews.
What data structure is used in Beautiful Arrangement?
Typical implementations use a boolean array or bitmask to track which numbers are already placed in the permutation. The optimized solution uses a bitmask integer combined with dynamic programming to represent subsets of chosen numbers efficiently.
What is the time complexity of Beautiful Arrangement?
The backtracking solution has worst‑case time complexity O(n!) because it explores permutations, but pruning significantly reduces the search space. The optimized dynamic programming solution using bitmasking runs in O(n * 2^n) time with O(2^n) space by storing results for each subset of numbers.
Beautiful Arrangement Python or Java solution approach?
In Python or Java, the standard solution uses recursion with backtracking. Maintain a visited array or bitmask, try placing each unused number at position i, and check the divisibility condition before recursing. The alternative implementation uses a DP array indexed by bitmask to count arrangements.
Is Beautiful Arrangement asked at Google, Amazon, or Meta?
Beautiful Arrangement appears frequently in coding interview preparation sets and has been reported in interviews at companies like Amazon and Google. The problem tests recursion, pruning strategies, and bitmask dynamic programming, which are common patterns in technical interviews.

Ready to solve this problem?

Practice Beautiful Arrangement with our built-in code editor and test cases.

Practice on FleetCode