10000 solve #131 · tinycedar/leetcode-rust@1530d3c · GitHub
[go: up one dir, main page]

Skip to content

Commit 1530d3c

Browse files
committed
solve #131
1 parent 70a73d2 commit 1530d3c

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,4 @@ mod n0127_word_ladder;
129129
mod n0128_longest_consecutive_sequence;
130130
mod n0129_sum_root_to_leaf_numbers;
131131
mod n0130_surrounded_regions;
132+
mod n0131_palindrome_partitioning;

src/n0131_palindrome_partitioning.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* [131] Palindrome Partitioning
3+
*
4+
* Given a string s, partition s such that every substring of the partition is a palindrome.
5+
*
6+
* Return all possible palindrome partitioning of s.
7+
*
8+
* Example:
9+
*
10+
*
11+
* Input: "aab"
12+
* Output:
13+
* [
14+
* ["aa","b"],
15+
* ["a","a","b"]
16+
* ]
17+
*
18+
*
19+
*/
20+
pub struct Solution {}
21+
22+
// submission codes start here
23+
24+
/*
25+
记 n 个字符的回文拆分方式是 f(n) 种, 则:
26+
27+
f(n) = (0..n).iter().fold(0, |acc, i| {
28+
if is_palindrome(s[i..n]) { acc + f(i-1) } else { acc }
29+
})
30+
31+
按这种方式向上递推即可, 时间复杂度为 O(N^3), 空间复杂度 O(N), 显然, is_palindrome 这一步仍然有重复计算
32+
33+
is_palindrome(s[i..n]) = s[i] == s[n] && is_palindrome(s[i+1..n-1])
34+
35+
存储所有 i, n 的 is_palindrome 结果, 则可以优化 is_palindrome 的时间到 O(1)
36+
37+
最后的复杂度: 时间 O(N^2), 空间 O(N^2)
38+
*/
39+
impl Solution {
40+
pub fn partition(s: String) -> Vec<Vec<String>> {
41+
let s = s.chars().collect::<Vec<_>>();
42+
if s.is_empty() { return Vec::new() }
43+
let mut palindrome_cache = vec![vec![None; s.len()]; s.len()];
44+
let mut res: Vec<Vec<Vec<(usize, usize)>>> = Vec::with_capacity(s.len());
45+
res.push(vec![vec![(0,1)]]);
46+
for n in 1..s.len() {
47+
let mut curr: Vec<Vec<(usize, usize)>> = Vec::new();
48+
for i in 0..n+1 {
49+
if Solution::is_palindrome(&mut palindrome_cache, &s, i, n) {
50+
if i > 0 {
51+
for vec in res[i-1].iter() {
52+
let mut new_vec = vec.clone();
53+
new_vec.push((i,n+1));
54+
curr.push(new_vec);
55+
}
56+
} else {
57+
curr.push(vec![(i, n+1)]);
58+
}
59+
}
60+
}
61+
res.push(curr);
62+
}
63+
(*res[s.len()-1]).into_iter().map(|vec| {
64+
vec.iter()
65+
.map(|&range| {s[range.0..range.1].iter().collect::<String>()})
66+
.collect::<Vec<_>>()
67+
}).collect()
68+
}
69+
70+
fn is_palindrome(cache: &Vec<Vec<Option<bool>>>, s: &Vec<char>, i: usize, j: usize) -> bool {
71+
if j <= i { return true }
72+
if let Some(result) = cache[i][j] {
73+
result
74+
} else {
75+
s[i] == s[j] && (i + 1 > s.len() || j < 1 || Solution::is_palindrome(cache, s, i+1, j-1))
76+
}
77+
}
78+
}
79+
80+
// submission codes end
81+
82+
#[cfg(test)]
83+
mod tests {
84+
use super::*;
85+
86+
#[test]
87+
fn test_131() {
88+
assert_eq!(
89+
Solution::partition("aab".to_owned()),
90+
vec![
91+
vec_string!["aa", "b"],
92+
vec_string!["a", "a", "b"],
93+
]);
94+
assert_eq!(
95+
Solution::partition("aaa".to_owned()),
96+
vec![
97+
vec_string!["aaa"],
98+
vec_string!["a", "aa"],
99+
vec_string!["aa", "a"],
100+
vec_string!["a", "a", "a"],
101+
]);
102+
}
103+
}

0 commit comments

Comments
 (0)
0