1. Bottom-Up Dynamic Programming

class Solution:
    def numberOfWays(self, numPeople: int) -> int:
        m = 1000000007
        dp = [0] * (numPeople // 2 + 1)
        dp[0] = 1

        for i in range(1, numPeople // 2 + 1):
            for j in range(i):
                dp[i] += dp[j] * dp[i - j - 1]
                dp[i] %= m

        return dp[numPeople // 2]

Time & Space Complexity

  • Time complexity: O(numPeople2)O(numPeople^2)

  • Space complexity: O(numPeople)O(numPeople)


2. Top-Down Dynamic Programming (Memoization)

class Solution:
    def numberOfWays(self, numPeople: int) -> int:
        m = 1000000007
        dp = [-1] * (numPeople // 2 + 1)
        dp[0] = 1

        def calculate_dp(i):
            if dp[i] != -1:
                return dp[i]
            dp[i] = 0
            for j in range(i):
                dp[i] += calculate_dp(j) * calculate_dp(i - j - 1)
            dp[i] %= m
            return dp[i]

        return calculate_dp(numPeople // 2)

Time & Space Complexity

  • Time complexity: O(numPeople2)O(numPeople^2)

  • Space complexity: O(numPeople)O(numPeople)


3. Catalan Numbers

class Solution:
    def numberOfWays(self, numPeople: int) -> int:
        m = 1000000007
        n = numPeople // 2
        inv = [None] * (n+2)
        inv[1] = 1
        for i in range(2, n+2):
            k = m // i
            r = m % i
            inv[i] = m - k * inv[r] % m

        C = 1
        for i in range(n):
            C = 2 * (2 * i + 1) * inv[i + 2] * C % m

        return C

Time & Space Complexity

  • Time complexity: O(numPeople)O(numPeople)

  • Space complexity: O(numPeople)O(numPeople)