-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpermutation_in_string.rs
103 lines (87 loc) · 2.72 KB
/
permutation_in_string.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::collections::HashMap;
/// Given two strings `s1` and `s2`, return `true` if `s2` contains a permutation of `s1`, or
/// `false` otherwise.
///
/// In other words, return `true` if one of `s1`'s permutations is the substring of `s2`.
struct Solution;
impl Solution {
fn counts(s1: String) -> HashMap<char, usize> {
let mut result = HashMap::new();
for letter in s1.chars() {
result
.entry(letter)
.and_modify(|count| *count += 1)
.or_insert(1);
}
result
}
pub fn check_inclusion(s1: String, s2: String) -> bool {
let s1_len = s1.len();
let s2_len = s2.len();
if s2_len < s1_len {
false
} else {
let mut result = false;
let s1_counts = Self::counts(s1);
let s2_letters: Vec<char> = s2.chars().collect();
let mut s2_counts = HashMap::new();
for i in 0..s1_len {
let letter = s2_letters[i];
s2_counts
.entry(letter)
.and_modify(|count| *count += 1)
.or_insert(1);
}
let mut right = s1_len - 1;
loop {
if s1_counts == s2_counts {
result = true;
break;
} else if right == s2_len - 1 {
break;
} else {
let left = right + 1 - s1_len;
let letter = s2_letters[left];
s2_counts
.entry(letter)
.and_modify(|count| *count -= 1);
if s2_counts[&letter] == 0 {
s2_counts.remove(&letter);
}
right += 1;
let letter = s2_letters[right];
s2_counts
.entry(letter)
.and_modify(|count| *count += 1)
.or_insert(1);
}
}
result
}
}
}
#[cfg(test)]
mod tests {
use super::Solution;
#[test]
fn example_1() {
let s1 = "ab".to_string();
let s2 = "eidbaooo".to_string();
let result = Solution::check_inclusion(s1, s2);
assert!(result);
}
#[test]
fn example_2() {
let s1 = "ab".to_string();
let s2 = "eidboaoo".to_string();
let result = Solution::check_inclusion(s1, s2);
assert!(!result);
}
#[test]
fn example_3() {
let s1 = "abc".to_string();
let s2 = "ccccbbbbaaaa".to_string();
let result = Solution::check_inclusion(s1, s2);
assert!(!result);
}
}