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.
// C++ program to find nth catalan number
#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;
}
// Java program to find nth catalan number
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);
}
}
# Python program to find nth catalan number
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)
// C# program to find nth catalan number
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);
}
}
// JavaScript program to find nth catalan number
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;
}
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].
// C++ program to find nth catalan number
#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;
}
// Java program to find nth catalan number
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);
}
}
# Python program to find nth catalan number
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)
// C# program to find nth catalan number
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);
}
}
// JavaScript program to find nth catalan number
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).
// C++ program for nth Catalan Number
#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
long long findCatalan(int n)
{
// Calculate value of 2nCn
long long c = binomialCoeff(2 * n, n);
// return 2nCn/(n+1)
return 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 long findCatalan(int n)
{
// Calculate value of 2nCn
long c = binomialCoeff(2 * n, n);
// return 2nCn/(n+1)
return c / (n + 1);
}
public static void main(String[] args)
{
int n = 3;
long 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 long findCatalan(int n)
{
// Calculate value of 2nCn
long c = binomialCoeff(2 * n, n);
// return 2nCn/(n+1)
return c / (n + 1);
}
static void Main()
{
int n = 3;
long 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.
// C++ program for nth Catalan Number
#include <iostream>
using namespace std;
long long findCatalan(int n)
{
long long res = 1;
for (int i = 2; i <= n; i++)
{
res = (res * (4 * i - 2)) / (i + 1);
}
return res;
}
//Driver Code
int main()
{
int n = 3;
int res = findCatalan(n);
cout << res;
return 0;
}
public class GfG {
public static long findCatalan(int n) {
long res = 1;
for (int i = 2; i <= n; i++) {
res = (res * (4 * i - 2)) / (i + 1);
}
return res;
}
public static void main(String[] args) {
int n = 3;
long res = findCatalan(n);
System.out.println(res);
}
}
def findCatalan(n):
res = 1
for i in range(2, n + 1):
res = (res * (4 * i - 2)) // (i + 1)
return res
#Driver Code
n = 3
res = findCatalan(n)
print(res)
using System;
public class GfG {
public static long findCatalan(int n) {
long res = 1;
for (int i = 2; i <= n; i++) {
res = (res * (4 * i - 2)) / (i + 1);
}
return res;
}
public static void Main() {
int n = 3;
long res = findCatalan(n);
Console.WriteLine(res);
}
}
function findCatalan(n) {
let res = 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)