From 131514e25a9e7cc6d2065ea61e348cfd1be64f67 Mon Sep 17 00:00:00 2001 From: Thanaphoom Babparn Date: Sat, 8 Feb 2025 20:31:47 +0900 Subject: [PATCH 1/4] Add longest_substring_with_unique_chars --- .../longest_substring_with_unique_chars.rs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 rust/Sliding Windows/longest_substring_with_unique_chars.rs diff --git a/rust/Sliding Windows/longest_substring_with_unique_chars.rs b/rust/Sliding Windows/longest_substring_with_unique_chars.rs new file mode 100644 index 0000000..62a8f1e --- /dev/null +++ b/rust/Sliding Windows/longest_substring_with_unique_chars.rs @@ -0,0 +1,26 @@ +fn longest_substring_with_unique_chars(s: String) -> i32 { + use std::collections::HashSet; + + let mut max_len = 0; + let mut hash_set = HashSet::new(); + let mut left = 0; + let mut right = 0; + let s = s.as_bytes(); + + while right < s.len() { + // If we encounter a duplicate character in the window, shrink + // the window until it's no longer a duplicate. + while hash_set.contains(&s[right]) { + hash_set.remove(&s[left]); + left += 1; + } + // Once there are no more duplicates in the window, update + // 'max_len' if the current window is larger. + max_len = max_len.max(right - left + 1); + hash_set.insert(s[right]); + // Expand the window. + right += 1; + } + + max_len as i32 +} From fc87f3a73fdbcd734b69825ae584979c7e7105d0 Mon Sep 17 00:00:00 2001 From: Thanaphoom Babparn Date: Sat, 8 Feb 2025 20:31:56 +0900 Subject: [PATCH 2/4] Add longest_substring_with_unique_chars_optimized --- ...t_substring_with_unique_chars_optimized.rs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 rust/Sliding Windows/longest_substring_with_unique_chars_optimized.rs diff --git a/rust/Sliding Windows/longest_substring_with_unique_chars_optimized.rs b/rust/Sliding Windows/longest_substring_with_unique_chars_optimized.rs new file mode 100644 index 0000000..d04b696 --- /dev/null +++ b/rust/Sliding Windows/longest_substring_with_unique_chars_optimized.rs @@ -0,0 +1,30 @@ +fn longest_substring_with_unique_chars_optimized(s: String) -> i32 { + use std::collections::HashMap; + + let mut max_len = 0; + let mut prev_indexes = HashMap::new(); + let mut left = 0; + let mut right = 0; + // Shadowing 's' by converting it to a byte array/slice. + let s = s.as_bytes(); + + while right < s.len() { + // If a previous index of the current character is present + // in the current window, it's a duplicate character in the + // window. + if let Some(&prev_index) = prev_indexes.get(&s[right]) { + // Shrink the window to exclude the previous occurrence + // of this character. + if prev_index >= left { + left = prev_index + 1; + } + } + // Update 'max_len' if the current window is larger. + max_len = max_len.max(right - left + 1); + prev_indexes.insert(s[right], right); + // Expand the window. + right += 1; + } + + max_len as i32 +} \ No newline at end of file From f3f08062a0c6cdfda948b4fcd2d18e8068afab0a Mon Sep 17 00:00:00 2001 From: Thanaphoom Babparn Date: Sat, 8 Feb 2025 20:32:04 +0900 Subject: [PATCH 3/4] Add longest_uniform_substring_after_replacements --- ...st_uniform_substring_after_replacements.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 rust/Sliding Windows/longest_uniform_substring_after_replacements.rs diff --git a/rust/Sliding Windows/longest_uniform_substring_after_replacements.rs b/rust/Sliding Windows/longest_uniform_substring_after_replacements.rs new file mode 100644 index 0000000..68da97b --- /dev/null +++ b/rust/Sliding Windows/longest_uniform_substring_after_replacements.rs @@ -0,0 +1,35 @@ +fn longest_uniform_substring_after_replacements(s: String, k: i32) -> i32 { + use std::collections::HashMap; + + let mut freqs = HashMap::new(); + let mut highest_freq = 0; + let mut max_len = 0; + let mut left = 0; + let mut right = 0; + let s = s.as_bytes(); + + while right < s.len() { + // Update the frequency of the character at the right pointer + // and the highest frequency for the current window. + *freqs.entry(s[right]).or_insert(0) += 1; + highest_freq = highest_freq.max(*freqs.get(&s[right]).unwrap()); + // Calculate replacements needed for the current window. + let num_chars_to_replace = ((right - left + 1) as i32) - highest_freq; + // Slide the window if the number of replacements needed exceeds + // 'k'. The right pointer always gets advanced, so we just need + // to advance 'left'. + if num_chars_to_replace > k { + // Remove the character at the left pointer from the hash map + // before advancing the left pointer. + *freqs.get_mut(&s[left]).unwrap() -= 1; + left += 1; + } + // Since the length of the current window increases or stays the + // same, assign the length of the current window to 'max_len'. + max_len = max_len.max(right - left + 1); + // Expand the window. + right += 1; + } + + max_len as i32 +} From f75eb21a4fbbb5bd7f0f20697c272e3cd6da25af Mon Sep 17 00:00:00 2001 From: Thanaphoom Babparn Date: Sat, 8 Feb 2025 20:32:11 +0900 Subject: [PATCH 4/4] Add substring_anagrams --- rust/Sliding Windows/substring_anagrams.rs | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 rust/Sliding Windows/substring_anagrams.rs diff --git a/rust/Sliding Windows/substring_anagrams.rs b/rust/Sliding Windows/substring_anagrams.rs new file mode 100644 index 0000000..8ba1a98 --- /dev/null +++ b/rust/Sliding Windows/substring_anagrams.rs @@ -0,0 +1,35 @@ +fn substring_anagrams(s: String, t: String) -> i32 { + let len_s = s.len(); + let len_t = t.len(); + if len_t > len_s { + return 0; + } + let mut count = 0; + let mut expected_freqs = vec![0; 26]; + let mut window_freqs = vec![0; 26]; + // Populate 'expected_freqs' with the characters in string 't'. + for c in t.bytes() { + expected_freqs[(c - b'a') as usize] += 1; + } + let mut left = 0; + let mut right = 0; + while right < len_s { + // Add the character at the right pointer to 'window_freqs' + // before sliding the window. + window_freqs[(s.as_bytes()[right] - b'a') as usize] += 1; + // If the window has reached the expected fixed length, we + // advance the left pointer as well as the right pointer to + // slide the window. + if right - left + 1 == len_t { + if window_freqs == expected_freqs { + count += 1; + } + // Remove the character at the left pointer from + // 'window_freqs' before advancing the left pointer. + window_freqs[(s.as_bytes()[left] - b'a') as usize] -= 1; + left += 1; + } + right += 1; + } + count +}