Given a number n, the task is to find the nth Catalan number.  Catalan Number for n is equal to the number of expressions containing n pairs of parenthesis that are correctly matched, i.e., for each of the n(' there exist n ')' on there right and vice versa. The first few Catalan numbers for n = 0, 1, 2, 3, 4, 5… are: 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, ...  so on.
Examples:
Input: n = 3
Output: 5
Explanation: For n = 3, there are 5 valid combinations of balanced parentheses: ((())), (()()), (())(), ()(()), ()()()Input: n = 4
Output: 14
Explanation: For n = 4, there are 14 distinct valid combinations of balanced parentheses that can be formed.
Catalan numbers are defined as a mathematical sequence that consists of positive integers, which can be used to find the number of possibilities of various combinations. The nth term in the sequence denoted Cn, is found in the following formula:
Â
Catalan numbers occur in many interesting counting problems like the following.
- Count the number of expressions containing n pairs of parentheses that are correctly matched.
- Count the number of possible Binary Search Trees with n keys (See this)
- Count the number of full binary trees (A rooted binary tree is full if every vertex has either two children or no children) with n+1 leaves.
- Given a number n, return the number of ways you can draw n chords in a circle with 2 x n points such that no 2 chords intersect.
Refer to this for more applications.Â
Table of Content
[Naive Approach] Using Recursion - O(2n) Time O(n) Space
Recursive formula: Â
C(n) = \sum_{i=0}^{n-1} C(i)\,C(n - i - 1) \ \text{for} \ i = 0 \ \text{to} \ n-1
The nth Catalan number is calculated using the recursive formula. We recursively compute smaller Catalan values and combine them.
Algorithm:
- If n ≤ 1, return 1 (base case).
- Initialize result = 0.
- Loop i from 0 to n-1, recursively calculate left = C(i) and right = C(n-i-1) and add left * right to the result.
#include <iostream>
using namespace std;
int findCatalan(int n)
{
// Base case
if (n <= 1)
return 1;
// catalan(n) is sum of
// catalan(i)*catalan(n-i-1)
int res = 0;
for (int i = 0; i < n; i++)
res += findCatalan(i) * findCatalan(n - i - 1);
return res;
}
int main()
{
int n = 3;
int res = findCatalan(n);
cout << res;
return 0;
}
class GFG {
static int findCatalan(int n)
{
// Base case
if (n <= 1) {
return 1;
}
// catalan(n) is the sum of catalan(i) *
// catalan(n-i-1)
int res = 0;
for (int i = 0; i < n; i++) {
res += findCatalan(i) * findCatalan(n - i - 1);
}
return res;
}
public static void main(String[] args)
{
int n = 3;
int res = findCatalan(n);
System.out.println(res);
}
}
def findCatalan(n):
# Base case
if n <= 1:
return 1
# catalan(n) is sum of catalan(i) * catalan(n-i-1)
res = 0
for i in range(n):
res += findCatalan(i) * findCatalan(n - i - 1)
return res
n = 3
res = findCatalan(n)
print(res)
using System;
class GFG {
static int findCatalan(int n)
{
// Base case
if (n <= 1)
return 1;
// catalan(n) is the sum of catalan(i) *
// catalan(n-i-1)
int res = 0;
for (int i = 0; i < n; i++) {
res += findCatalan(i) * findCatalan(n - i - 1);
}
return res;
}
static void Main(string[] args)
{
int n = 3;
int res = findCatalan(n);
Console.WriteLine(res);
}
}
function findCatalan(n)
{
// Base case
if (n <= 1) {
return 1;
}
// catalan(n) is the sum of catalan(i) * catalan(n-i-1)
let res = 0;
for (let i = 0; i < n; i++) {
res += findCatalan(i) * findCatalan(n - i - 1);
}
return res;
}
// Driver Code
let n = 3;
let res = findCatalan(n);
console.log(res);
Output
5
Time Complexity: O(2n)
Auxiliary Space:Â O(n)
[Better Approach] Dynamic Programming (Bottom-Up) - O(n) Time O(n) Space
The recursive solution has overlapping subproblems. So, we store previously computed Catalan numbers in an array and build the result from bottom-up using the same formula:
C(i) = \sum_{j=0}^{i-1} C(j)\,C(i - j - 1)
Algorithm:
- Create an array
catalan[]of size n+1 and Initializecatalan[0] = catalan[1] = 1. - Loop
ifrom 2 to n. For eachi, initializecatalan[i] = 0. - Run inner loop
jfrom 0 to i-1. Addcatalan[j] * catalan[i - j - 1]tocatalan[i]. - After filling the table, return
catalan[n].
#include <iostream>
using namespace std;
int findCatalan(int n)
{
// Table to store results of subproblems
int catalan[n + 1];
// Initialize first two values in table
catalan[0] = catalan[1] = 1;
// Fill entries in catalan[] using recursive formula
for (int i = 2; i <= n; i++)
{
catalan[i] = 0;
for (int j = 0; j < i; j++)
catalan[i] += catalan[j] * catalan[i - j - 1];
}
// Return last entry
return catalan[n];
}
int main()
{
int n = 3;
int res = findCatalan(n);
cout << res;
return 0;
}
class GFG {
static int findCatalan(int n)
{
// Table to store results of subproblems
int[] catalan = new int[n + 1];
// Initialize first two values in the table
catalan[0] = catalan[1] = 1;
// Fill entries in catalan[] using the recursive
// formula
for (int i = 2; i <= n; i++) {
catalan[i] = 0;
for (int j = 0; j < i; j++) {
catalan[i]
+= catalan[j] * catalan[i - j - 1];
}
}
// Return the last entry
return catalan[n];
}
public static void main(String[] args)
{
int n = 3;
int res = findCatalan(n);
System.out.println(res);
}
}
def findCatalan(n):
# Table to store results of subproblems
catalan = [0] * (n + 1)
# Initialize first two values in the table
catalan[0] = catalan[1] = 1
# Fill entries in catalan[] using the recursive formula
for i in range(2, n + 1):
catalan[i] = 0
for j in range(i):
catalan[i] += catalan[j] * catalan[i - j - 1]
# Return the last entry
return catalan[n]
n = 3
res = findCatalan(n)
print(res)
using System;
class GFG {
static int findCatalan(int n)
{
// Table to store results of subproblems
int[] catalan = new int[n + 1];
// Initialize first two values in the table
catalan[0] = catalan[1] = 1;
// Fill entries in catalan[] using the recursive
// formula
for (int i = 2; i <= n; i++) {
catalan[i] = 0;
for (int j = 0; j < i; j++) {
catalan[i]
+= catalan[j] * catalan[i - j - 1];
}
}
// Return the last entry
return catalan[n];
}
static void Main()
{
int n = 3;
int res = findCatalan(n);
Console.WriteLine(res);
}
}
function findCatalan(n)
{
// Table to store results of subproblems
let catalan = new Array(n + 1).fill(0);
// Initialize first two values in the table
catalan[0] = catalan[1] = 1;
// Fill entries in catalan[] using the recursive formula
for (let i = 2; i <= n; i++) {
catalan[i] = 0;
for (let j = 0; j < i; j++) {
catalan[i] += catalan[j] * catalan[i - j - 1];
}
}
// Return the last entry
return catalan[n];
}
let n = 3;
let res = findCatalan(n);
console.log(res);
Output
5
Time Complexity: O(n2)
Auxiliary Space: O(n)
[Expected Approach] Binomial Coefficient – O(n) Time O(1) Space
Catalan numbers can be directly computed using the mathematical formula:
Â
C_n = \frac{1}{n+1} \binom{2n}{n} Instead of recursion or DP, we efficiently compute the binomial coefficient and divide by (n + 1).
#include <iostream>
using namespace std;
// Returns value of Binomial Coefficient C(n, k)
long long binomialCoeff(int n, int k)
{
long long res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of [n*(n-1)*---*(n-k+1)] /
// [k*(k-1)*---*1]
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// A Binomial coefficient based function to find nth catalan
// number in O(n) time
int findCatalan(int n)
{
// Calculate value of 2nCn
long long c = binomialCoeff(2 * n, n);
// return 2nCn/(n+1)
return (int)(c / (n + 1));
}
int main()
{
int n = 3;
int res = findCatalan(n);
cout << res;
return 0;
}
public class GFG {
// Returns value of Binomial Coefficient C(n, k)
static long binomialCoeff(int n, int k)
{
long res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of [n*(n-1)*---*(n-k+1)] /
// [k*(k-1)*---*1]
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// A Binomial coefficient based function to find nth catalan
// number in O(n) time
static int findCatalan(int n)
{
// Calculate value of 2nCn
long c = binomialCoeff(2 * n, n);
// return 2nCn/(n+1)
// explicit cast: safe here since n <= 19 keeps the result within int range
return (int)(c / (n + 1));
}
public static void main(String[] args)
{
int n = 3;
int res = findCatalan(n);
System.out.println(res);
}
}
def binomialCoeff(n, k):
res = 1
# Since C(n, k) = C(n, n-k)
if k > n - k:
k = n - k
# Calculate value of [n*(n-1)*---*(n-k+1)] /
# [k*(k-1)*---*1]
for i in range(k):
res *= (n - i)
res //= (i + 1)
return res
# A Binomial coefficient based function to find nth catalan
# number in O(n) time
def findCatalan(n):
# Calculate value of 2nCn
c = binomialCoeff(2 * n, n)
# return 2nCn/(n+1)
return c // (n + 1)
n = 3
res = findCatalan(n)
print(res)
using System;
class GFG
{
// Returns value of Binomial Coefficient C(n, k)
static long binomialCoeff(int n, int k)
{
long res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of [n*(n-1)*---*(n-k+1)] /
// [k*(k-1)*---*1]
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// A Binomial coefficient based function to find nth catalan
// number in O(n) time
static int findCatalan(int n)
{
// Calculate value of 2nCn
long c = binomialCoeff(2 * n, n);
// return 2nCn/(n+1)
return (int)(c / (n + 1));
}
static void Main()
{
int n = 3;
int res = findCatalan(n);
Console.WriteLine(res);
}
}
function binomialCoeff(n, k) {
let res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of [n*(n-1)*---*(n-k+1)] /
// [k*(k-1)*---*1]
for (let i = 0; i < k; ++i) {
res *= (n - i);
res /= (i + 1);
}
return res;
}
// A Binomial coefficient based function to find nth catalan
// number in O(n) time
function findCatalan(n) {
// Calculate value of 2nCn
let c = binomialCoeff(2 * n, n);
// return 2nCn/(n+1)
return Math.floor(c / (n + 1));
}
let n = 3;
let res = findCatalan(n);
console.log(res);
Output
5
Time Complexity: O(n).
Auxiliary Space: O(1)
[Alternate Approach] Using Previous Catalan Number – O(n) Time O(1) Space
We already know how to calculate the nth Catalan Number using the below formula,
C_n = \frac{2n!}{(n+1)! \times n!} This formula can be further simplified to express the nth Catalan Number in the terms of (n-1)th Catalan Number,
C_n = C_{n-1} \times \left( \frac{4n - 2}{n + 1} \right)
Steps:
- Initialize res = 1 (Catalan(0) = 1).
- Loop from i = 2 to n. In each iteration, update result using formula: res = res * (4*i - 2) / (i + 1)
- This builds the current Catalan number using the previous one.
#include <iostream>
using namespace std;
int findCatalan(int n)
{
// res holds the current Catalan number at each step, starting from C(0) = 1
long long res = 1;
// build each Catalan number directly from the previous one,
// using the recurrence C(i) = C(i-1) * (4i-2)/(i+1)
for (int i = 2; i <= n; i++)
{
// res must stay 'long long' here: the intermediate multiplication
// (res * (4*i - 2)) can briefly exceed int range before the
// division brings it back down to the actual Catalan number
res = (res * (4 * i - 2)) / (i + 1);
}
// explicit cast: safe here since n <= 19 keeps the result within int range
return (int)res;
}
//Driver Code
int main()
{
int n = 3;
int res = findCatalan(n);
cout << res;
return 0;
}
public class GFG {
public static int findCatalan(int n) {
// res holds the current Catalan number at each step, starting from C(0) = 1
long res = 1;
// build each Catalan number directly from the previous one,
// using the recurrence C(i) = C(i-1) * (4i-2)/(i+1)
for (int i = 2; i <= n; i++) {
// res must stay 'long' here: the intermediate multiplication
// (res * (4*i - 2)) can briefly exceed int range before the
// division brings it back down to the actual Catalan number
res = (res * (4 * i - 2)) / (i + 1);
}
// explicit cast: safe here since n <= 19 keeps the result within int range
return (int) res;
}
public static void main(String[] args) {
int n = 3;
int res = findCatalan(n);
System.out.println(res);
}
}
def findCatalan(n):
# res holds the current Catalan number at each step, starting from C(0) = 1
res = 1
# build each Catalan number directly from the previous one,
# using the recurrence C(i) = C(i-1) * (4i-2)/(i+1)
for i in range(2, n + 1):
res = (res * (4 * i - 2)) // (i + 1)
return res
n = 3
res = findCatalan(n)
print(res)
using System;
public class GFG {
public static int findCatalan(int n) {
// res holds the current Catalan number at each step, starting from C(0) = 1
long res = 1;
// build each Catalan number directly from the previous one,
// using the recurrence C(i) = C(i-1) * (4i-2)/(i+1)
for (int i = 2; i <= n; i++) {
// res must stay 'long' here: the intermediate multiplication
// (res * (4*i - 2)) can briefly exceed int range before the
// division brings it back down to the actual Catalan number
res = (res * (4 * i - 2)) / (i + 1);
}
// explicit cast: safe here since n <= 19 keeps the result within int range
return (int)res;
}
public static void Main() {
int n = 3;
int res = findCatalan(n);
Console.WriteLine(res);
}
}
function findCatalan(n) {
// res holds the current Catalan number at each step, starting from C(0) = 1
let res = 1;
// build each Catalan number directly from the previous one,
// using the recurrence C(i) = C(i-1) * (4i-2)/(i+1)
for (let i = 2; i <= n; i++) {
res = Math.floor((res * (4 * i - 2)) / (i + 1));
}
return res;
}
//Driver Code
let n = 3;
let res = findCatalan(n);
console.log(res);
Output
5
Time Complexity: O(n)
Auxiliary Space: O(1)