Skip to content

Commit 58e65bb

Browse files
committed
update
1 parent 7a25602 commit 58e65bb

File tree

1 file changed

+35
-32
lines changed

1 file changed

+35
-32
lines changed

src/prob_30.rs

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,46 @@ impl Solution {
77
}
88
let word_len = words[0].len();
99
let target_len = words.len();
10-
if s.len() < target_len*word_len {
10+
if s.len() < target_len * word_len {
1111
return vec![];
1212
}
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();
2013
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;
4137
}
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);
4448
}
4549
}
46-
ans
4750
}
4851
}
4952

@@ -56,9 +59,9 @@ mod tests {
5659
#[test]
5760
fn test_find_substring() {
5861
let test_cases = vec![
62+
("barfoothefoobarman", vec!["foo","bar"], vec![0,9]),
5963
("a", vec!["a", "a"], vec![]),
6064
("lingmindraboofooowingdingbarrwingmonkeypoundcake", vec!["fooo","barr","wing","ding","wing"], vec![13]),
61-
("barfoothefoobarman", vec!["foo","bar"], vec![0,9]),
6265
("wordgoodgoodgoodbestword", vec!["word","good","best","word"], vec![]),
6366
("wordgoodwordgoodbestwordword", vec!["word","good","best","word"], vec![8, 12]),
6467

0 commit comments

Comments
 (0)