Каталонские числа представляют собой последовательность натуральных чисел, которая встречается во многих интересных проблемах подсчета, таких как следующие.
1) Подсчитайте количество выражений, содержащих n пар скобок, которые правильно сопоставлены. Для n = 3 возможными выражениями являются ((())), () (()), () () (), (()) (), (() ()).
2) Подсчитайте количество возможных деревьев бинарного поиска с n ключами (см. Это )
3) Подсчитайте количество полных двоичных деревьев (корневое двоичное дерево заполнено, если у каждой вершины есть либо два потомка, либо нет потомков) с n + 1 листом.
Смотрите это для других приложений.
Первые несколько каталонских чисел для n = 0, 1, 2, 3,… являются 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862,…
Рекурсивное решение
Каталонские числа удовлетворяют следующей рекурсивной формуле.

Ниже приведена реализация приведенной выше рекурсивной формулы.
C ++
#include<iostream>
using namespace std;
unsigned long int catalan(unsigned int n)
{
if (n <= 1) return 1;
unsigned long int res = 0;
for ( int i=0; i<n; i++)
res += catalan(i)*catalan(n-i-1);
return res;
}
int main()
{
for ( int i=0; i<10; i++)
cout << catalan(i) << " " ;
return 0;
}
|
Джава
class CatalnNumber {
int catalan( int n) {
int res = 0 ;
if (n <= 1 ) {
return 1 ;
}
for ( int i = 0 ; i < n; i++) {
res += catalan(i) * catalan(n - i - 1 );
}
return res;
}
public static void main(String[] args) {
CatalnNumber cn = new CatalnNumber();
for ( int i = 0 ; i < 10 ; i++) {
System.out.print(cn.catalan(i) + " " );
}
}
}
|
питон
def catalan(n):
if n < = 1 :
return 1
res = 0
for i in range (n):
res + = catalan(i) * catalan(n - i - 1 )
return res
for i in range ( 10 ):
print catalan(i),
|
C #
using System;
class GFG {
static int catalan( int n) {
int res = 0;
if (n <= 1) {
return 1;
}
for ( int i = 0; i < n; i++)
{
res += catalan(i)
* catalan(n - i - 1);
}
return res;
}
public static void Main()
{
for ( int i = 0; i < 10; i++)
Console.Write(catalan(i)
+ " " );
}
}
|
PHP
<?php
function catalan( $n )
{
if ( $n <= 1)
return 1;
$res = 0;
for ( $i = 0; $i < $n ; $i ++)
$res += catalan( $i ) *
catalan( $n - $i - 1);
return $res ;
}
for ( $i = 0; $i < 10; $i ++)
echo catalan( $i ), " " ;
?>
|
Выход :
1 1 2 5 14 42 132 429 1430 4862
Временная сложность вышеуказанной реализации эквивалентна n-му каталонскому числу.

Значение n-го каталонского числа является экспоненциальным, что делает сложность времени экспоненциальной.
Решение для динамического программирования
Мы можем заметить, что вышеописанная рекурсивная реализация выполняет много повторяющихся операций (мы можем сделать то же самое, рисуя дерево рекурсии). Поскольку существуют перекрывающиеся подзадачи, мы можем использовать для этого динамическое программирование. Ниже приводится реализация на основе динамического программирования.
C ++
#include<iostream>
using namespace std;
unsigned long int catalanDP(unsigned int n)
{
unsigned long int catalan[n+1];
catalan[0] = catalan[1] = 1;
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 catalan[n];
}
int main()
{
for ( int i = 0; i < 10; i++)
cout << catalanDP(i) << " " ;
return 0;
}
|
Джава
class GFG{
static int catalanDP( int n) {
int catalan[] = new int [n + 2 ];
catalan[ 0 ] = 1 ;
catalan[ 1 ] = 1 ;
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 catalan[n];
}
public static void main(String[] args) {
for ( int i = 0 ; i < 10 ; i++) {
System.out.print(catalanDP(i) + " " );
}
}
}
|
питон
def catalan(n):
if (n = = 0 or n = = 1 ):
return 1
catalan = [ 0 for i in range (n + 1 )]
catalan[ 0 ] = 1
catalan[ 1 ] = 1
for i in range ( 2 , n + 1 ):
catalan[i] = 0
for j in range (i):
catalan[i] = catalan[i] + catalan[j] * catalan[i - j - 1 ]
return catalan[n]
for i in range ( 10 ):
print (catalan(i),end = " " )
|
C #
using System;
class GFG
{
static uint catalanDP( uint n)
{
uint [] catalan = new uint [n + 2];
catalan[0] = catalan[1] = 1;
for ( uint i = 2; i <= n; i++)
{
catalan[i] = 0;
for ( uint j = 0; j < i; j++)
catalan[i] += catalan[j] * catalan[i - j - 1];
}
return catalan[n];
}
static void Main()
{
for ( uint i = 0; i < 10; i++)
Console.Write(catalanDP(i) + " " );
} }
|
PHP
<?php
function catalanDP( $n )
{
$catalan = array ();
$catalan [0] = $catalan [1] = 1;
for ( $i = 2; $i <= $n ; $i ++)
{
$catalan [ $i ] = 0;
for ( $j = 0; $j < $i ; $j ++)
$catalan [ $i ] += $catalan [ $j ] *
$catalan [ $i - $j - 1];
}
return $catalan [ $n ];
}
for ( $i = 0; $i < 10; $i ++)
echo catalanDP( $i ) , " " ;
?>
|
Выход:
1 1 2 5 14 42 132 429 1430 4862
Сложность времени: временная сложность вышеописанной реализации составляет O (n 2 )
Использование биномиального коэффициента
Мы также можем использовать приведенную ниже формулу, чтобы найти n-е каталонское число за O (n) время.

Мы обсудили O (n) подход, чтобы найти биномиальный коэффициент nCr .
C ++
#include<iostream>
using namespace std;
unsigned long int binomialCoeff(unsigned int n, unsigned int k)
{
unsigned long int res = 1;
if (k > n - k)
k = n - k;
for ( int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
unsigned long int catalan(unsigned int n)
{
unsigned long int c = binomialCoeff(2*n, n);
return c/(n+1);
}
int main()
{
for ( int i = 0; i < 10; i++)
cout << catalan(i) << " " ;
return 0;
}
|
Джава
class GFG {
static long binomialCoeff( int n, int k) {
long res = 1 ;
if (k > n - k) {
k = n - k;
}
for ( int i = 0 ; i < k; ++i) {
res *= (n - i);
res /= (i + 1 );
}
return res;
}
static long catalan( int n) {
long c = binomialCoeff( 2 * n, n);
return c / (n + 1 );
}
public static void main(String[] args) {
for ( int i = 0 ; i < 10 ; i++) {
System.out.print(catalan(i) + " " );
}
}
}
|
python3
def binomialCoefficient(n, k):
if (k > n - k):
k = n - k
res = 1
for i in range (k):
res = res * (n - i)
res = res / (i + 1 )
return res
def catalan(n):
c = binomialCoefficient( 2 * n, n)
return c / (n + 1 )
for i in range ( 10 ):
print (catalan(i),end = " " )
|
C #
using System;
class GFG
{
static long binomialCoeff( int n, int k)
{
long res = 1;
if (k > n - k)
{
k = n - k;
}
for ( int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
static long catalan( int n)
{
long c = binomialCoeff(2 * n, n);
return c / (n + 1);
}
public static void Main()
{
for ( int i = 0; i < 10; i++) {
Console.Write(catalan(i) + " " );
}
}
}
|
PHP
<?php
function binomialCoeff( $n , $k )
{
$res = 1;
if ( $k > $n - $k )
$k = $n - $k ;
for ( $i = 0; $i < $k ; ++ $i )
{
$res *= ( $n - $i );
$res = floor ( $res / ( $i + 1));
}
return $res ;
}
function catalan( $n )
{
$c = binomialCoeff(2 * ( $n ), $n );
return floor ( $c / ( $n + 1));
}
for ( $i = 0; $i < 10; $i ++)
echo catalan( $i ), " " ;
?>
|
Выход:
1 1 2 5 14 42 132 429 1430 4862
Сложность времени: временная сложность вышеописанной реализации составляет O (n).
Мы также можем использовать приведенную ниже формулу, чтобы найти n-е каталонское число за O (n) время.

Ссылки:
http://en.wikipedia.org/wiki/Catalan_number
Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме
Рекомендуемые посты:
Программа для n-го каталонского номера
0.00 (0%) 0 votes