|
@@ -0,0 +1,67 @@
|
|
|
+struct Solution;
|
|
|
+
|
|
|
+use std::collections::{HashMap, VecDeque};
|
|
|
+
|
|
|
+impl Solution {
|
|
|
+ pub fn min_window(s: String, t: String) -> String {
|
|
|
+ let s_bytes = s.as_bytes();
|
|
|
+ let t_bytes = t.as_bytes();
|
|
|
+ let mut map = HashMap::<u8, i32>::new();
|
|
|
+ let mut n_free = t.len() as i32;
|
|
|
+
|
|
|
+ let (mut len, mut pos) = (s.len(), 0);
|
|
|
+
|
|
|
+ for &b in t_bytes {
|
|
|
+ let count = map.entry(b).or_insert(0);
|
|
|
+ *count += 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ let mut window = VecDeque::<usize>::new();
|
|
|
+
|
|
|
+ for (i, b) in s_bytes.iter().enumerate() {
|
|
|
+ if let Some(count) = map.get_mut(&b) {
|
|
|
+ *count -= 1;
|
|
|
+ window.push_back(i);
|
|
|
+
|
|
|
+ if *count >= 0 {
|
|
|
+ n_free -= 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ while let Some(&idx) = window.front() {
|
|
|
+ let cur_count = map.get_mut(&s_bytes[idx]).unwrap();
|
|
|
+ if *cur_count < 0 {
|
|
|
+ *cur_count += 1;
|
|
|
+ window.pop_front();
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if n_free == 0 {
|
|
|
+ let cur_len = i - *window.front().unwrap();
|
|
|
+ if cur_len < len {
|
|
|
+ len = cur_len;
|
|
|
+ pos = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len == s.len() {
|
|
|
+ "".to_owned()
|
|
|
+ } else {
|
|
|
+ String::from(&s[pos - len..pos + 1])
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(test)]
|
|
|
+mod tests {
|
|
|
+ use super::*;
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_min_window1() {
|
|
|
+ let s = String::from("ADOBECODEBANC");
|
|
|
+ let t = String::from("ABC");
|
|
|
+ let res = Solution::min_window(s, t);
|
|
|
+ assert_eq!(res, String::from("BANC"));
|
|
|
+ }
|
|
|
+}
|