@@ -7,43 +7,46 @@ impl Solution {
7
7
}
8
8
let word_len = words[ 0 ] . len ( ) ;
9
9
let target_len = words. len ( ) ;
10
- if s. len ( ) < target_len* word_len {
10
+ if s. len ( ) < target_len * word_len {
11
11
return vec ! [ ] ;
12
12
}
13
- let mut words_map = HashMap :: new ( ) ;
14
- for word in words. iter ( ) {
15
- * words_map. entry ( word. clone ( ) ) . or_insert ( 0 ) += 1 ;
16
- }
17
- let s_len = s. len ( ) ;
18
- let last_idx = s_len-target_len* word_len;
19
- let bytes = s. as_bytes ( ) ;
20
13
let mut ans = vec ! [ ] ;
21
- let mut current = HashMap :: new ( ) ;
22
- let mut count = 0 ;
23
- for i in 0 ..=last_idx {
24
- let mut j = i;
25
- let mut success = true ;
26
- current. clear ( ) ;
27
- for _ in 0 ..target_len {
28
- let next_j = j+word_len;
29
- let cs = unsafe { std:: str:: from_utf8_unchecked ( & bytes[ j..next_j] ) . to_string ( ) } ;
30
- j = next_j;
31
- if !words_map. contains_key ( & cs) {
32
- success = false ;
33
- break ;
34
- }
35
- let p = current. entry ( cs. clone ( ) ) . or_insert ( 0 ) ;
36
- * p += 1 ;
37
- if * p > * words_map. get ( & cs) . unwrap ( ) {
38
- success = false ;
39
- break ;
40
- }
14
+ let mut count = HashMap :: new ( ) ;
15
+ for w in & words {
16
+ * count. entry ( w. as_str ( ) ) . or_insert ( 0 ) += 1 ;
17
+ }
18
+ let sb = s. as_bytes ( ) ;
19
+ for i in 0 ..word_len {
20
+ Self :: find ( & sb[ i..] , i, word_len, & count, target_len, & mut ans) ;
21
+ }
22
+ ans
23
+ }
24
+ fn find ( s : & [ u8 ] , idx : usize , len : usize , words : & HashMap < & str , i32 > , total : usize , ans : & mut Vec < i32 > ) {
25
+ let mut i = 0 ;
26
+ let mut j = 0 ;
27
+ let mut cur = HashMap :: new ( ) ;
28
+ let mut acc = 0 ;
29
+ while j+len <= s. len ( ) {
30
+ let t = unsafe { std:: str:: from_utf8_unchecked ( & s[ j..j+len] ) } ;
31
+ j += len;
32
+ if !words. contains_key ( t) {
33
+ i = j;
34
+ cur. clear ( ) ;
35
+ acc = 0 ;
36
+ continue ;
41
37
}
42
- if success && current == words_map {
43
- ans. push ( i as i32 ) ;
38
+ * cur. entry ( t) . or_insert ( 0 ) += 1 ;
39
+ acc += 1 ;
40
+ while * cur. get ( & t) . unwrap ( ) > * words. get ( t) . unwrap ( ) {
41
+ let p = unsafe { std:: str:: from_utf8_unchecked ( & s[ i..i+len] ) } ;
42
+ i += len;
43
+ * cur. get_mut ( & p) . unwrap ( ) -= 1 ;
44
+ acc -= 1 ;
45
+ }
46
+ if acc == total {
47
+ ans. push ( ( i+idx) as i32 ) ;
44
48
}
45
49
}
46
- ans
47
50
}
48
51
}
49
52
@@ -56,9 +59,9 @@ mod tests {
56
59
#[ test]
57
60
fn test_find_substring ( ) {
58
61
let test_cases = vec ! [
62
+ ( "barfoothefoobarman" , vec![ "foo" , "bar" ] , vec![ 0 , 9 ] ) ,
59
63
( "a" , vec![ "a" , "a" ] , vec![ ] ) ,
60
64
( "lingmindraboofooowingdingbarrwingmonkeypoundcake" , vec![ "fooo" , "barr" , "wing" , "ding" , "wing" ] , vec![ 13 ] ) ,
61
- ( "barfoothefoobarman" , vec![ "foo" , "bar" ] , vec![ 0 , 9 ] ) ,
62
65
( "wordgoodgoodgoodbestword" , vec![ "word" , "good" , "best" , "word" ] , vec![ ] ) ,
63
66
( "wordgoodwordgoodbestwordword" , vec![ "word" , "good" , "best" , "word" ] , vec![ 8 , 12 ] ) ,
64
67
0 commit comments