|
1 | 1 | #![allow(dead_code)]
|
| 2 | + |
| 3 | +use std::collections::HashMap; |
2 | 4 | pub fn min_window(s: String, t: String) -> String {
|
3 |
| - if t.len() > s.len() { |
4 |
| - return "".to_string(); |
| 5 | + let s: Vec<char> = s.chars().collect(); |
| 6 | + |
| 7 | + if t.is_empty() || s.len() < t.len() { |
| 8 | + return String::new(); |
5 | 9 | }
|
6 | 10 |
|
7 |
| - let need_map = t.chars().fold([0; 128], |mut acc, c| { |
8 |
| - acc[c as usize] += 1; |
9 |
| - acc |
10 |
| - }); |
11 |
| - let mut window_map = [0; 128]; |
12 |
| - let mut left = 0; |
13 |
| - let mut right = 0; |
14 |
| - let mut count = 0; |
15 |
| - let mut min_substring = "".to_string(); |
16 |
| - |
17 |
| - while right < s.len() { |
18 |
| - let c = s.chars().nth(right).unwrap(); |
19 |
| - window_map[c as usize] += 1; |
20 |
| - if window_map[c as usize] <= need_map[c as usize] { |
21 |
| - count += 1; |
22 |
| - } |
| 11 | + let mut l = 0; |
| 12 | + let mut res = (-1, -1); |
| 13 | + let mut res_len = usize::MAX; |
| 14 | + let mut count_t: HashMap<char, usize> = HashMap::new(); |
| 15 | + let mut window: HashMap<char, _> = HashMap::new(); |
| 16 | + |
| 17 | + for c in t.chars() { |
| 18 | + *count_t.entry(c).or_default() += 1; |
| 19 | + } |
| 20 | + |
| 21 | + let need = count_t.len(); |
| 22 | + let mut have = 0; |
| 23 | + |
| 24 | + for r in 0..s.len() { |
| 25 | + let c = s[r]; |
23 | 26 |
|
24 |
| - // If the window contains all the characters in t |
25 |
| - // Try to shrink the window |
26 |
| - while count == t.len() { |
27 |
| - let c = s.chars().nth(left).unwrap(); |
28 |
| - if right - left + 1 < min_substring.len() || min_substring.is_empty() { |
29 |
| - min_substring = s[left..=right].to_string(); |
| 27 | + *window.entry(c).or_default() += 1; |
| 28 | + have += (window.get(&c) == count_t.get(&c)) as usize; |
| 29 | + |
| 30 | + while have == need { |
| 31 | + if (r - l + 1) < res_len { |
| 32 | + res = (l as i32, r as i32); |
| 33 | + res_len = r - l + 1; |
30 | 34 | }
|
31 |
| - window_map[c as usize] -= 1; |
32 |
| - if window_map[c as usize] < need_map[c as usize] { |
33 |
| - count -= 1; |
| 35 | + *window.get_mut(&s[l]).unwrap() -= 1; |
| 36 | + |
| 37 | + if window.get(&s[l]) < count_t.get(&s[l]) { |
| 38 | + have -= 1; |
34 | 39 | }
|
35 |
| - left += 1; |
| 40 | + |
| 41 | + l += 1; |
36 | 42 | }
|
37 |
| - right += 1; |
38 | 43 | }
|
39 | 44 |
|
40 |
| - min_substring |
| 45 | + if res.0 > -1 && res.1 > -1 { |
| 46 | + return s[res.0 as usize..=res.1 as usize].into_iter().collect(); |
| 47 | + } |
| 48 | + |
| 49 | + String::new() |
41 | 50 | }
|
42 | 51 |
|
43 | 52 | /*
|
44 | 53 | Algorithm - Sliding Window
|
45 |
| - - Create a need_map to store the number of characters in t |
46 |
| - - Create a window_map to store the number of characters in the window |
47 |
| - - Create a count to store the number of characters in the window that matches the characters in t |
48 |
| - - Create a left and right pointer to shrink and expand the window |
49 |
| - - Create a min_substring to store the minimum substring that contains all the characters in t |
50 |
| - - Loop through the string |
51 |
| - - If the window contains all the characters in t |
52 |
| - - Try to shrink the window |
53 |
| - - If the window is smaller than the min_substring |
54 |
| - - Update the min_substring |
55 |
| - - If the window does not contain all the characters in t |
56 |
| - - Try to expand the window |
57 |
| - - Return the min_substring |
58 |
| -
|
59 |
| - Time: O(n) |
60 |
| - Space: O(n) |
| 54 | + Time complexity: O(n) |
| 55 | + Space complexity: O(n) |
| 56 | +
|
| 57 | + - Create a hashmap of the characters in t and their count |
| 58 | + - Create a hashmap of the characters in the window and their count |
| 59 | + - Create a variable to keep track of the number of unique characters in t |
| 60 | + - Create a variable to keep track of the number of unique characters in the window |
| 61 | + - Create a variable to keep track of the left index of the window |
| 62 | + - Create a variable to keep track of the right index of the window |
| 63 | + - Create a variable to keep track of the minimum window length |
| 64 | + - Create a variable to keep track of the minimum window indices |
| 65 | + - Iterate through the string |
| 66 | + - Add the current character to the window hashmap |
| 67 | + - If the count of the current character in the window hashmap is equal to the count of the current character in the t hashmap, increment the number of unique characters in the window |
| 68 | + - While the number of unique characters in the window is equal to the number of unique characters in t |
| 69 | + - If the current window length is less than the minimum window length, update the minimum window length and indices |
| 70 | + - Remove the leftmost character from the window hashmap |
| 71 | + - If the count of the leftmost character in the window hashmap is less than the count of the leftmost character in the t hashmap, decrement the number of unique characters in the window |
| 72 | + - Increment the left index of the window |
| 73 | + - If the minimum window indices are valid, return the substring of the minimum window indices |
| 74 | + - Otherwise, return an empty string |
| 75 | +
|
61 | 76 | */
|
62 | 77 |
|
63 | 78 | #[cfg(test)]
|
|
0 commit comments