ProCodebaseProCodebase
  • ModusA Growth OS for your business, on WhatsAppKiosqSell more. Chase less.AI InterviewerAutomated screening & AI-led interviewsXperto AIAI prep companion for candidatesAI Tools HubResume builder, learning paths & more
  • Pre-Vetted DevelopersScreened, scored and ready to interviewAI-Native DevelopersSenior engineers on an hourly basis
  • Services
  • Features
  • Jobs
  • FAQs
Sign inBook a demo
  • Services
  • Features
  • Jobs
  • FAQs
Sign inBook a demo
ProCodebaseProCodebase

ProCodebase Technologies builds AI products for hiring and growth, and ships software for clients as a technical consultancy. We source, screen and deliver pre-vetted developers — so you only interview high-signal candidates.

Products

  • Modus
  • Kiosq
  • AI Interviewer
  • Xperto AI
  • AI Tools Hub

Hire & build

  • Pre-Vetted Developers
  • AI-Native Developers
  • Technical Consultancy
  • MVP Development
  • Features

Resources

  • Articles
  • Topics
  • Certifications
  • Collections
  • Jobs

Company

  • About Us
  • Contact Us
  • Book a Demo
  • FAQs

© 2026 ProCodebase Technologies. All rights reserved.

  • Privacy Policy
  • Terms & Conditions
  • Refund & Cancellation

Level Up Your Skills with Xperto-AI

A multi-AI agent platform that helps you level up your development skills and ace your interview preparation to secure your dream job.

Launch Xperto-AI

Generate All Valid Parentheses

author
Generated by
Anushka Agrawal

13/10/2024

DSA

Sign in to read full article

Generating all valid parentheses is a classic problem in the realm of data structures and algorithms (DSA), especially when diving into the advanced concepts of recursion and backtracking. This problem not only helps reinforce the understanding of recursion but also provides a solid foundation for more complex branching problems. In this blog, we’ll break down the problem, approach it step-by-step, and implement it in Java.

Problem Statement

The problem requires us to generate all combinations of valid parentheses given n pairs of parentheses. A pair of parentheses is a "(" followed by a ")". For example, if n = 3, the valid combinations would be:

  • ((()))
  • (()())
  • (())()
  • ()(())
  • ()()()

Understanding Valid Parentheses

A combination of parentheses is considered valid if:

  1. For any prefix of the string, the number of ( is always greater than or equal to the number of ).
  2. At the end of the string, both counts must be equal (i.e., balanced).

To visualize, consider a simple case where n = 2:

  • The valid combinations are ()() and (()). Notice how both count as valid because they follow the rules defined above.

Approach

To solve this problem, we can use a combination of backtracking and recursion:

  1. Maintain count variables for how many open ( and close ) parentheses we have already placed.
  2. Use these counts to decide when to add more ( or ) to the current combination.
  3. Recursively build the parentheses string and add valid combinations to the results list.

Steps

  • If the count of open parentheses is less than n, we can add an open parenthesis (.
  • If the count of closed parentheses is less than the count of open parentheses, we can add a closing parenthesis ).
  • Continue this process until the length of the current string equals 2 * n.

Implementation in Java

Here’s a Java implementation that demonstrates the above approach:

import java.util.ArrayList; import java.util.List; public class GenerateParentheses { public static List<String> generateParenthesis(int n) { List<String> results = new ArrayList<>(); backtrack(results, "", 0, 0, n); return results; } private static void backtrack(List<String> results, String current, int open, int close, int max) { if (current.length() == max * 2) { results.add(current); return; } // Add an open parenthesis if we can if (open < max) { backtrack(results, current + "(", open + 1, close, max); } // Add a close parenthesis if we can if (close < open) { backtrack(results, current + ")", open, close + 1, max); } } public static void main(String[] args) { int n = 3; List<String> parenthesis = generateParenthesis(n); System.out.println("Valid combinations of " + n + " pairs of parentheses: " + parenthesis); } }

Explanation:

  1. Base Case: When the length of the current string is equal to 2 * n, we add the string to results since it represents a valid combination.
  2. Recursion:
    • Adding (: We ensure we can add more ( if the count hasn't reached n.
    • Adding ): We ensure the count of ) is less than the number of ( to maintain balance.

This approach efficiently explores all possibilities while adhering to the constraints of valid combinations.

Visualizing the Backtracking Process

Consider how the backtracking works visually. For n = 3, the function starts with an empty string and explores adding (, followed by potential placements of ). As it constructs each combination step by step, it backtracks whenever it reaches a point where it cannot add more parentheses without violating the conditions set forth.

By using recursion and backtracking, we ensure that all valid combinations are considered while unnecessary paths are pruned early, making the solution efficient.

This not only demonstrates the power of recursion in solving complex problems but also provides a rigorous practice session for understanding backtracking in algorithm design.

Embrace the beauty of recursion and backtracking as you tackle similar problems in your coding journey!

Popular tags

DSAJavaRecursion

Share now!

Like & bookmark

Related collections

  • Advanced Dynamic Programming Interview Questions

    15/11/2024 · DSA

  • DSA Mastery for Interviews

    23/09/2024 · DSA

  • Trees Interview Questions Using Java

    13/10/2024 · DSA

  • Mastering Bit Manipulation: Unlocking Binary Power

    08/12/2024 · DSA

  • Top 20 DSA Interview Questions Mastery

    23/09/2024 · DSA

Related articles

  • Largest Sum Subarray

    06/12/2024 · DSA

  • Understanding the Unique Paths Problem

    15/11/2024 · DSA

  • Frequency Sort Using Priority Queue

    16/11/2024 · DSA

  • Understanding Lowest Common Ancestor in Binary Trees

    13/10/2024 · DSA

  • Binary Search Using Tree Data Structures

    04/08/2024 · DSA

  • Understanding Union-Find and Graph Connectivity

    16/11/2024 · DSA

  • The Word Break Problem

    15/11/2024 · DSA

Popular category

  • Python
  • Generative AI
  • Machine Learning
  • ReactJS
  • System Design