Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2d1bfc4

Browse files
feat: add Catalan numbers implementation using dynamic programming (TheAlgorithms#961)
1 parent 1a27c6c commit 2d1bfc4

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

‎DIRECTORY.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
* [Union Find](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/union_find.rs)
8888
* [Veb Tree](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/veb_tree.rs)
8989
* Dynamic Programming
90+
* [Catalan Numbers](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/catalan_numbers.rs)
9091
* [Coin Change](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/coin_change.rs)
9192
* [Egg Dropping](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/egg_dropping.rs)
9293
* [Fibonacci](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/fibonacci.rs)
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//! Catalan Numbers using Dynamic Programming
2+
//!
3+
//! The Catalan numbers are a sequence of positive integers that appear in many
4+
//! counting problems in combinatorics. Such problems include counting:
5+
//! - The number of Dyck words of length 2n
6+
//! - The number of well-formed expressions with n pairs of parentheses
7+
//! (e.g., `()()` is valid but `())(` is not)
8+
//! - The number of different ways n + 1 factors can be completely parenthesized
9+
//! (e.g., for n = 2, C(n) = 2 and (ab)c and a(bc) are the two valid ways)
10+
//! - The number of full binary trees with n + 1 leaves
11+
//!
12+
//! A Catalan number satisfies the following recurrence relation:
13+
//! - C(0) = C(1) = 1
14+
//! - C(n) = sum(C(i) * C(n-i-1)), from i = 0 to n-1
15+
//!
16+
//! Sources:
17+
//! - [Brilliant.org](https://brilliant.org/wiki/catalan-numbers/)
18+
//! - [Wikipedia](https://en.wikipedia.org/wiki/Catalan_number)
19+
20+
/// Computes the Catalan number sequence from 0 through `upper_limit`.
21+
///
22+
/// # Arguments
23+
///
24+
/// * `upper_limit` - The upper limit for the Catalan sequence (must be ≥ 0)
25+
///
26+
/// # Returns
27+
///
28+
/// A vector containing Catalan numbers from C(0) to C(upper_limit)
29+
///
30+
/// # Complexity
31+
///
32+
/// * Time complexity: O(n2)
33+
/// * Space complexity: O(n)
34+
///
35+
/// where `n` is the `upper_limit`.
36+
///
37+
/// # Examples
38+
///
39+
/// ```
40+
/// use the_algorithms_rust::dynamic_programming::catalan_numbers;
41+
///
42+
/// assert_eq!(catalan_numbers(5), vec![1, 1, 2, 5, 14, 42]);
43+
/// assert_eq!(catalan_numbers(2), vec![1, 1, 2]);
44+
/// assert_eq!(catalan_numbers(0), vec![1]);
45+
/// ```
46+
///
47+
/// # Warning
48+
///
49+
/// This will overflow the 64-bit unsigned integer for large values of `upper_limit`.
50+
/// For example, C(21) and beyond will cause overflow.
51+
pub fn catalan_numbers(upper_limit: usize) -> Vec<u64> {
52+
let mut catalan_list = vec![0u64; upper_limit + 1];
53+
54+
// Base case: C(0) = 1
55+
catalan_list[0] = 1;
56+
57+
// Base case: C(1) = 1
58+
if upper_limit > 0 {
59+
catalan_list[1] = 1;
60+
}
61+
62+
// Recurrence relation: C(i) = sum(C(j) * C(i-j-1)), from j = 0 to i-1
63+
for i in 2..=upper_limit {
64+
for j in 0..i {
65+
catalan_list[i] += catalan_list[j] * catalan_list[i - j - 1];
66+
}
67+
}
68+
69+
catalan_list
70+
}
71+
72+
#[cfg(test)]
73+
mod tests {
74+
use super::*;
75+
76+
#[test]
77+
fn test_catalan_numbers_basic() {
78+
assert_eq!(catalan_numbers(5), vec![1, 1, 2, 5, 14, 42]);
79+
assert_eq!(catalan_numbers(2), vec![1, 1, 2]);
80+
assert_eq!(catalan_numbers(0), vec![1]);
81+
}
82+
83+
#[test]
84+
fn test_catalan_numbers_single() {
85+
assert_eq!(catalan_numbers(1), vec![1, 1]);
86+
}
87+
88+
#[test]
89+
fn test_catalan_numbers_extended() {
90+
let result = catalan_numbers(10);
91+
assert_eq!(result.len(), 11);
92+
assert_eq!(result[0], 1);
93+
assert_eq!(result[1], 1);
94+
assert_eq!(result[2], 2);
95+
assert_eq!(result[3], 5);
96+
assert_eq!(result[4], 14);
97+
assert_eq!(result[5], 42);
98+
assert_eq!(result[6], 132);
99+
assert_eq!(result[7], 429);
100+
assert_eq!(result[8], 1430);
101+
assert_eq!(result[9], 4862);
102+
assert_eq!(result[10], 16796);
103+
}
104+
105+
#[test]
106+
fn test_catalan_first_few() {
107+
// Verify the first few Catalan numbers match known values
108+
assert_eq!(catalan_numbers(3), vec![1, 1, 2, 5]);
109+
assert_eq!(catalan_numbers(4), vec![1, 1, 2, 5, 14]);
110+
}
111+
}

‎src/dynamic_programming/mod.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod catalan_numbers;
12
mod coin_change;
23
mod egg_dropping;
34
mod fibonacci;
@@ -22,6 +23,7 @@ mod task_assignment;
2223
mod trapped_rainwater;
2324
mod word_break;
2425

26+
pub use self::catalan_numbers::catalan_numbers;
2527
pub use self::coin_change::coin_change;
2628
pub use self::egg_dropping::egg_drop;
2729
pub use self::fibonacci::binary_lifting_fibonacci;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /