githubEdit

25. Number of Valid Parentheses

βœ… GFG solution to Number of Valid Parentheses problem using Catalan numbers, binomial coefficient optimization, and dynamic programming. πŸš€

The problem can be found at the following link: πŸ”— Question Linkarrow-up-right

🧩 Problem Description

You are given a number n, your task is to find the number of all the valid parentheses expressions of that length using only "(" and ")" brackets.

An input string of parentheses is valid if:

  • Open brackets must be closed in correct order.

  • Every close bracket has a corresponding open bracket.

For example - "()()" or "(())" are valid while ")()(" or "))((" are invalid parentheses expressions.

πŸ“˜ Examples

Example 1

Input: n = 2
Output: 1
Explanation: There is only one possible valid expression of length 2 i.e., "()".

Example 2

Input: n = 4
Output: 2
Explanation: Possible valid expressions of length 4 are "(())" and "()()".

Example 3

πŸ”’ Constraints

  • $1 \le n \le 20$

βœ… My Approach

The problem of counting valid parentheses expressions is directly related to Catalan Numbers. The n-th Catalan number represents the number of valid ways to arrange n pairs of parentheses.

Binomial Coefficient Formula (Optimized)

  1. Check Validity:

    • If n is odd, return 0 immediately (valid parentheses always have even length).

    • Divide n by 2 to get the number of pairs.

  2. Calculate Catalan Number:

    • Use the formula: C(n) = C(2n, n) / (n + 1)

    • Where C(2n, n) is the binomial coefficient "2n choose n".

  3. Efficient Computation:

    • Calculate C(2n, n) iteratively using: res = res * (2n - i) / (i + 1)

    • This approach avoids overflow by alternating multiplication and division.

  4. Final Result:

    • Divide the binomial coefficient by (n + 1) to get the Catalan number.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), as we perform a single loop that runs n/2 times to calculate the binomial coefficient, where n is the input length.

  • Expected Auxiliary Space Complexity: O(1), as we only use a constant amount of additional space with variables for calculation.

βš™οΈ Code (C)

πŸ§‘β€πŸ’» Code (C++)

chevron-right⚑ View Alternative Approaches with Code and Analysishashtag

πŸ“Š 2️⃣ Dynamic Programming Approach

πŸ’‘ Algorithm Steps:

  1. Create a DP array where dp[i] represents the i-th Catalan number.

  2. Use the recurrence relation: C(n) = Ξ£ C(i) * C(n-1-i) for i from 0 to n-1.

  3. Build up from base case C(0) = 1 to compute C(n/2).

  4. Return the computed Catalan number which represents valid parentheses count.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(nΒ²) - Nested loops for DP computation

  • Auxiliary Space: πŸ’Ύ O(n) - DP array storage

βœ… Why This Approach?

  • Demonstrates the recursive nature of Catalan numbers

  • Useful for computing multiple Catalan numbers

  • Intuitive understanding of parentheses nesting

πŸ“Š 3️⃣ Direct Formula Approach

πŸ’‘ Algorithm Steps:

  1. Use the direct formula: C(n) = (2n)! / ((n+1)! * n!)

  2. Simplify to avoid large factorial computations.

  3. Calculate using iterative multiplication and division.

  4. Return the final Catalan number.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Single loop iteration

  • Auxiliary Space: πŸ’Ύ O(1) - Constant space usage

βœ… Why This Approach?

  • Mathematically elegant solution

  • Optimal space complexity

  • Efficient computation without recursion

πŸ“Š 4️⃣ Recursive Memoization

πŸ’‘ Algorithm Steps:

  1. Define recursive function: catalan(n) = Ξ£ catalan(i) * catalan(n-1-i).

  2. Use memoization to store computed values.

  3. Base case: catalan(0) = 1.

  4. Return memoized result for n/2.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(nΒ²) - Recursive calls with memoization

  • Auxiliary Space: πŸ’Ύ O(n) - Memoization map and recursion stack

βœ… Why This Approach?

  • Natural recursive formulation

  • Avoids recomputation with memoization

  • Good for understanding problem structure

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

🏷️ Binomial Direct

🟒 O(n)

🟒 O(1)

πŸš€ Fastest execution

πŸ”§ Overflow risk if not careful

πŸ” Dynamic Programming

🟑 O(n²)

🟑 O(n)

πŸ“– Clear recurrence pattern

🐌 Slower for large n

πŸ“Š Direct Formula

🟒 O(n)

🟒 O(1)

🎯 Mathematically clean

πŸ”’ Division order matters

πŸ”„ Recursive Memoization

🟑 O(n²)

🟑 O(n)

⭐ Natural formulation

πŸ”§ Stack overflow for large n

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

πŸ… Optimal performance needed

πŸ₯‡ Binomial Direct

β˜…β˜…β˜…β˜…β˜…

πŸ“– Learning Catalan numbers

πŸ₯ˆ Dynamic Programming

β˜…β˜…β˜…β˜…β˜†

πŸ”§ Mathematical elegance

πŸ₯‰ Direct Formula

β˜…β˜…β˜…β˜…β˜…

🎯 Interview/Competitive

πŸ… Binomial Direct

β˜…β˜…β˜…β˜…β˜…

β˜• Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?arrow-up-right. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated