Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Beautiful Arrangement

Updated
3 min read

Introduction

In this blog post, we will explore how to solve the LeetCode problem "526" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

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

Explanation

Here's the solution:

  • Backtracking with Pruning: The core idea is to use backtracking to explore all possible permutations. However, we add a crucial pruning step: at each position i, we only consider numbers that satisfy the beautiful arrangement condition (either perm[i] is divisible by i or i is divisible by perm[i]). This significantly reduces the search space.
  • Bitmasking for Visited Numbers: We use a bitmask to keep track of which numbers have already been used in the permutation. This allows for efficient checking of availability and marking/unmarking during the backtracking process.
  • Dynamic Programming (Memoization): Even with backtracking and pruning, exploring all permutations for n=15 can still be time-consuming. To further optimize, we can use memoization, storing the results of subproblems (the number of arrangements possible given a specific state - current index and used numbers). The lru_cache decorator makes this easy.

  • Runtime Complexity: O(n!), where n is the input integer. Because of pruning and memoization, it is significantly faster than raw O(n!). Storage Complexity: O(n * 2^n) due to memoization and bitmasking.

Code

    from functools import lru_cache

def countArrangement(n: int) -> int:
    """
    Calculates the number of beautiful arrangements for n integers.

    Args:
        n: The number of integers (1 to n).

    Returns:
        The number of beautiful arrangements.
    """

    @lru_cache(None)
    def solve(index: int, mask: int) -> int:
        """
        Recursive helper function to count arrangements.

        Args:
            index: The current index to fill (1-indexed).
            mask: A bitmask representing which numbers have been used.

        Returns:
            The number of beautiful arrangements possible from this state.
        """

        if index > n:
            return 1  # Base case: all positions filled

        count = 0
        for num in range(1, n + 1):
            if not (mask & (1 << (num - 1))):  # Check if num is not used
                if (num % index == 0) or (index % num == 0):
                    count += solve(index + 1, mask | (1 << (num - 1)))

        return count

    return solve(1, 0)

More from this blog

C

Chatmagic blog

2894 posts

Solving Leetcode Interviews in Seconds with AI: Beautiful Arrangement