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 5c4593c

Browse files
feat: add Palindrome Partitioning algorithm (TheAlgorithms#971)
1 parent 98400e1 commit 5c4593c

File tree

3 files changed

+137
-4
lines changed

3 files changed

+137
-4
lines changed

‎DIRECTORY.md‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
* [Maximum Subarray](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/maximum_subarray.rs)
111111
* [Minimum Cost Path](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/minimum_cost_path.rs)
112112
* [Optimal BST](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/optimal_bst.rs)
113+
* [Palindrome Partitioning](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/palindrome_partitioning.rs)
113114
* [Rod Cutting](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/rod_cutting.rs)
114115
* [Smith-Waterman](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/smith_waterman.rs)
115116
* [Snail](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/snail.rs)
@@ -150,7 +151,7 @@
150151
* [Segment](https://github.com/TheAlgorithms/Rust/blob/master/src/geometry/segment.rs)
151152
* Graph
152153
* [Astar](https://github.com/TheAlgorithms/Rust/blob/master/src/graph/astar.rs)
153-
* [BellmanFord](https://github.com/TheAlgorithms/Rust/blob/master/src/graph/bellman_ford.rs)
154+
* [Bellman-Ford](https://github.com/TheAlgorithms/Rust/blob/master/src/graph/bellman_ford.rs)
154155
* [Bipartite Matching](https://github.com/TheAlgorithms/Rust/blob/master/src/graph/bipartite_matching.rs)
155156
* [Breadth First Search](https://github.com/TheAlgorithms/Rust/blob/master/src/graph/breadth_first_search.rs)
156157
* [Centroid Decomposition](https://github.com/TheAlgorithms/Rust/blob/master/src/graph/centroid_decomposition.rs)
@@ -233,12 +234,12 @@
233234
* [Geometric Series](https://github.com/TheAlgorithms/Rust/blob/master/src/math/geometric_series.rs)
234235
* [Greatest Common Divisor](https://github.com/TheAlgorithms/Rust/blob/master/src/math/greatest_common_divisor.rs)
235236
* [Huber Loss](https://github.com/TheAlgorithms/Rust/blob/master/src/math/huber_loss.rs)
236-
* [Infix To Postfix](https://github.com/TheAlgorithms/Rust/blob/master/src/math/infix_to_postfix.rs)
237+
* [Infix to Postfix](https://github.com/TheAlgorithms/Rust/blob/master/src/math/infix_to_postfix.rs)
237238
* [Interest](https://github.com/TheAlgorithms/Rust/blob/master/src/math/interest.rs)
238239
* [Interpolation](https://github.com/TheAlgorithms/Rust/blob/master/src/math/interpolation.rs)
239240
* [Interquartile Range](https://github.com/TheAlgorithms/Rust/blob/master/src/math/interquartile_range.rs)
240241
* [Karatsuba Multiplication](https://github.com/TheAlgorithms/Rust/blob/master/src/math/karatsuba_multiplication.rs)
241-
* [LCM Of N Numbers](https://github.com/TheAlgorithms/Rust/blob/master/src/math/lcm_of_n_numbers.rs)
242+
* [LCM of N Numbers](https://github.com/TheAlgorithms/Rust/blob/master/src/math/lcm_of_n_numbers.rs)
242243
* [Leaky Relu](https://github.com/TheAlgorithms/Rust/blob/master/src/math/leaky_relu.rs)
243244
* [Least Square Approx](https://github.com/TheAlgorithms/Rust/blob/master/src/math/least_square_approx.rs)
244245
* [Linear Sieve](https://github.com/TheAlgorithms/Rust/blob/master/src/math/linear_sieve.rs)
@@ -249,7 +250,7 @@
249250
* [Miller Rabin](https://github.com/TheAlgorithms/Rust/blob/master/src/math/miller_rabin.rs)
250251
* [Modular Exponential](https://github.com/TheAlgorithms/Rust/blob/master/src/math/modular_exponential.rs)
251252
* [Newton Raphson](https://github.com/TheAlgorithms/Rust/blob/master/src/math/newton_raphson.rs)
252-
* [Nthprime](https://github.com/TheAlgorithms/Rust/blob/master/src/math/nthprime.rs)
253+
* [N-th prime](https://github.com/TheAlgorithms/Rust/blob/master/src/math/nthprime.rs)
253254
* [Pascal Triangle](https://github.com/TheAlgorithms/Rust/blob/master/src/math/pascal_triangle.rs)
254255
* [Perfect Cube](https://github.com/TheAlgorithms/Rust/blob/master/src/math/perfect_cube.rs)
255256
* [Perfect Numbers](https://github.com/TheAlgorithms/Rust/blob/master/src/math/perfect_numbers.rs)

‎src/dynamic_programming/mod.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ mod maximal_square;
1414
mod maximum_subarray;
1515
mod minimum_cost_path;
1616
mod optimal_bst;
17+
mod palindrome_partitioning;
1718
mod rod_cutting;
1819
mod smith_waterman;
1920
mod snail;
@@ -47,6 +48,7 @@ pub use self::maximal_square::maximal_square;
4748
pub use self::maximum_subarray::maximum_subarray;
4849
pub use self::minimum_cost_path::minimum_cost_path;
4950
pub use self::optimal_bst::optimal_search_tree;
51+
pub use self::palindrome_partitioning::minimum_palindrome_partitions;
5052
pub use self::rod_cutting::rod_cut;
5153
pub use self::smith_waterman::{score_function, smith_waterman, traceback};
5254
pub use self::snail::snail;
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/// Finds the minimum cuts needed for a palindrome partitioning of a string
2+
///
3+
/// Given a string s, partition s such that every substring of the partition is a palindrome.
4+
/// This function returns the minimum number of cuts needed.
5+
///
6+
/// Time Complexity: O(n^2)
7+
/// Space Complexity: O(n^2)
8+
///
9+
/// # Arguments
10+
///
11+
/// * `s` - The input string to partition
12+
///
13+
/// # Returns
14+
///
15+
/// The minimum number of cuts needed
16+
///
17+
/// # Examples
18+
///
19+
/// ```
20+
/// use the_algorithms_rust::dynamic_programming::minimum_palindrome_partitions;
21+
///
22+
/// assert_eq!(minimum_palindrome_partitions("aab"), 1);
23+
/// assert_eq!(minimum_palindrome_partitions("aaa"), 0);
24+
/// assert_eq!(minimum_palindrome_partitions("ababbbabbababa"), 3);
25+
/// ```
26+
///
27+
/// # Algorithm Explanation
28+
///
29+
/// The algorithm uses dynamic programming with two key data structures:
30+
/// - `cut[i]`: minimum cuts needed for substring from index 0 to i
31+
/// - `is_palindromic[j][i]`: whether substring from index j to i is a palindrome
32+
///
33+
/// For each position i, we check all possible starting positions j to determine
34+
/// if the substring s[j..=i] is a palindrome. If it is, we update the minimum
35+
/// cut count accordingly.
36+
///
37+
/// Reference: <https://www.youtube.com/watch?v=_H8V5hJUGd0>
38+
pub fn minimum_palindrome_partitions(s: &str) -> usize {
39+
let chars: Vec<char> = s.chars().collect();
40+
let length = chars.len();
41+
42+
if length == 0 {
43+
return 0;
44+
}
45+
46+
// cut[i] represents the minimum cuts needed for substring from 0 to i
47+
let mut cut = vec![0; length];
48+
49+
// is_palindromic[j][i] represents whether substring from j to i is a palindrome
50+
let mut is_palindromic = vec![vec![false; length]; length];
51+
52+
for i in 0..length {
53+
let mut mincut = i;
54+
55+
for j in 0..=i {
56+
// Check if substring from j to i is a palindrome
57+
// A substring is a palindrome if:
58+
// 1. The characters at both ends match (chars[i] == chars[j])
59+
// 2. AND either:
60+
// - The substring length is less than 2 (single char or two same chars)
61+
// - OR the inner substring (j+1 to i-1) is also a palindrome
62+
if chars[i] == chars[j] && (i - j < 2 || is_palindromic[j + 1][i - 1]) {
63+
is_palindromic[j][i] = true;
64+
mincut = if j == 0 {
65+
// If the entire substring from 0 to i is a palindrome, no cuts needed
66+
0
67+
} else {
68+
// Otherwise, take minimum of current mincut and (cuts up to j-1) + 1
69+
mincut.min(cut[j - 1] + 1)
70+
};
71+
}
72+
}
73+
74+
cut[i] = mincut;
75+
}
76+
77+
cut[length - 1]
78+
}
79+
80+
#[cfg(test)]
81+
mod tests {
82+
use super::*;
83+
84+
#[test]
85+
fn test_basic_cases() {
86+
// "aab" -> "aa" | "b" = 1 cut
87+
assert_eq!(minimum_palindrome_partitions("aab"), 1);
88+
89+
// "aaa" is already a palindrome = 0 cuts
90+
assert_eq!(minimum_palindrome_partitions("aaa"), 0);
91+
92+
// Complex case
93+
assert_eq!(minimum_palindrome_partitions("ababbbabbababa"), 3);
94+
}
95+
96+
#[test]
97+
fn test_edge_cases() {
98+
// Empty string
99+
assert_eq!(minimum_palindrome_partitions(""), 0);
100+
101+
// Single character is always a palindrome
102+
assert_eq!(minimum_palindrome_partitions("a"), 0);
103+
104+
// Two different characters need 1 cut
105+
assert_eq!(minimum_palindrome_partitions("ab"), 1);
106+
}
107+
108+
#[test]
109+
fn test_palindromes() {
110+
// Already a palindrome
111+
assert_eq!(minimum_palindrome_partitions("racecar"), 0);
112+
assert_eq!(minimum_palindrome_partitions("noon"), 0);
113+
assert_eq!(minimum_palindrome_partitions("abba"), 0);
114+
}
115+
116+
#[test]
117+
fn test_non_palindromes() {
118+
// All different characters need n-1 cuts
119+
assert_eq!(minimum_palindrome_partitions("abcde"), 4);
120+
121+
// Two pairs need 1 cut
122+
assert_eq!(minimum_palindrome_partitions("aabb"), 1);
123+
}
124+
125+
#[test]
126+
fn test_longer_strings() {
127+
assert_eq!(minimum_palindrome_partitions("aaabaa"), 1);
128+
assert_eq!(minimum_palindrome_partitions("abcbm"), 2);
129+
}
130+
}

0 commit comments

Comments
(0)

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