diff --git a/src/problem/mod.rs b/src/problem/mod.rs index 0d4e7c2..f2a0127 100644 --- a/src/problem/mod.rs +++ b/src/problem/mod.rs @@ -114,4 +114,5 @@ mod p68_text_justification; mod p125_valid_palindrome; mod p392_is_subsequence; mod p167_two_sum_ii_input_array_is_sorted; -mod p209_minimum_size_subarray_sum; \ No newline at end of file +mod p209_minimum_size_subarray_sum; +mod p30_substring_with_concatenation_of_all_words; \ No newline at end of file diff --git a/src/problem/p30_substring_with_concatenation_of_all_words.rs b/src/problem/p30_substring_with_concatenation_of_all_words.rs new file mode 100644 index 0000000..7621a2a --- /dev/null +++ b/src/problem/p30_substring_with_concatenation_of_all_words.rs @@ -0,0 +1,85 @@ +/** + * [30] Substring with Concatenation of All Words + */ +pub struct Solution {} + +// submission codes start here +use std::collections::HashMap; + +impl Solution { + pub fn find_substring(s: String, words: Vec) -> Vec { + let mut result = Vec::new(); + + let m = words.len(); + let n = words[0].len(); + let ls = s.len(); + + for start in 0..n { + if start + m * n > ls { + break; + } + + let mut differ = HashMap::new(); + + for i in 0..m { + let word = s[start + i * n..start + i * n + n].to_owned(); + + let entry = differ.entry(word).or_insert(0); + *entry += 1; + } + + for word in (&words).to_owned() { + let entry = differ.entry(word.clone()).or_insert(0); + *entry -= 1; + + if *entry == 0 { + differ.remove(&word); + } + } + + // 滑动窗口开始滑动 + for i in (start..ls - m * n + 1).step_by(n) { + if i != start { + // 新加入的word + let end_word = s[i + (m - 1) * n..i + m * n].to_owned(); + let entry = differ.entry(end_word.clone()).or_insert(0); + *entry += 1; + + if *entry == 0 { + differ.remove(&end_word); + } + + // 滑动后被移除的word + let begin_word = s[i - n..i].to_owned(); + let entry = differ.entry(begin_word.clone()).or_insert(0); + *entry -= 1; + + if *entry == 0 { + differ.remove(&begin_word); + } + } + + if differ.len() == 0 { + result.push(i as i32); + } + } + } + + result + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_30() { + assert_eq!(vec![0,9], Solution::find_substring("barfoothefoobarman".to_owned(), vec![ + "foo".to_owned(), + "bar".to_owned() + ])) + } +}