|
| 1 | +/** |
| 2 | + * [30] 串联所有单词的子串 |
| 3 | + * |
| 4 | + * 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 |
| 5 | + * s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 |
| 6 | + * |
| 7 | + * 例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd","cdabef", "cdefab","efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。 |
| 8 | + * |
| 9 | + * 返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。 |
| 10 | + * |
| 11 | + * 示例 1: |
| 12 | + * |
| 13 | + * 输入:s = "barfoothefoobarman", words = ["foo","bar"] |
| 14 | + * 输出:[0,9] |
| 15 | + * 解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。 |
| 16 | + * 子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。 |
| 17 | + * 子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。 |
| 18 | + * 输出顺序无关紧要。返回 [9,0] 也是可以的。 |
| 19 | + * |
| 20 | + * 示例 2: |
| 21 | + * |
| 22 | + * 输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"] |
| 23 | + * 输出:[] |
| 24 | + * 解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。 |
| 25 | + * s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。 |
| 26 | + * 所以我们返回一个空数组。 |
| 27 | + * |
| 28 | + * 示例 3: |
| 29 | + * |
| 30 | + * 输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"] |
| 31 | + * 输出:[6,9,12] |
| 32 | + * 解释:因为 words.length == 3 并且 words[i].length == 3,所以串联子串的长度必须为 9。 |
| 33 | + * 子串 "foobarthe" 开始位置是 6。它是 words 中以 ["foo","bar","the"] 顺序排列的连接。 |
| 34 | + * 子串 "barthefoo" 开始位置是 9。它是 words 中以 ["bar","the","foo"] 顺序排列的连接。 |
| 35 | + * 子串 "thefoobar" 开始位置是 12。它是 words 中以 ["the","foo","bar"] 顺序排列的连接。 |
| 36 | + * |
| 37 | + * 提示: |
| 38 | + * |
| 39 | + * 1 <= s.length <= 10^4 |
| 40 | + * 1 <= words.length <= 5000 |
| 41 | + * 1 <= words[i].length <= 30 |
| 42 | + * words[i] 和 s 由小写英文字母组成 |
| 43 | + * |
| 44 | + */ |
| 45 | +pub struct Solution {} |
| 46 | + |
| 47 | +// problem: https://leetcode.cn/problems/substring-with-concatenation-of-all-words/ |
| 48 | +// discuss: https://leetcode.cn/problems/substring-with-concatenation-of-all-words/discuss/?currentPage=1&orderBy=most_votes&query= |
| 49 | + |
| 50 | +// submission codes start here |
| 51 | + |
| 52 | +impl Solution { |
| 53 | + pub fn find_substring(s: String, words: Vec<String>) -> Vec<i32> { |
| 54 | + let word_len = words[0].len(); |
| 55 | + let substr_len = word_len * words.len(); |
| 56 | + if substr_len > s.len() { |
| 57 | + return vec![]; |
| 58 | + } |
| 59 | + let mut sorted_words = words; |
| 60 | + sorted_words.sort(); |
| 61 | + |
| 62 | + let mut res = vec![]; |
| 63 | + for i in 0..s.len() - substr_len { |
| 64 | + let mut tmp_list = vec![]; |
| 65 | + let substr = &s[i..i + substr_len]; |
| 66 | + for j in (0..substr_len).step_by(word_len) { |
| 67 | + tmp_list.push(&substr[j..j + word_len]); |
| 68 | + } |
| 69 | + tmp_list.sort(); |
| 70 | + if tmp_list == sorted_words { |
| 71 | + res.push(i as i32); |
| 72 | + } |
| 73 | + } |
| 74 | + res |
| 75 | + } |
| 76 | +} |
| 77 | + |
| 78 | +// submission codes end |
| 79 | + |
| 80 | +#[cfg(test)] |
| 81 | +mod tests { |
| 82 | + use super::*; |
| 83 | + |
| 84 | + #[test] |
| 85 | + fn test_30() { |
| 86 | + assert_eq!( |
| 87 | + Solution::find_substring("hello".to_string(), vec!["ll".to_string()]), |
| 88 | + vec![2], |
| 89 | + ); |
| 90 | + assert_eq!( |
| 91 | + Solution::find_substring( |
| 92 | + "barfoothefoobarman".to_string(), |
| 93 | + vec!["foo".to_string(), "bar".to_string()] |
| 94 | + ), |
| 95 | + vec![0, 9], |
| 96 | + ); |
| 97 | + assert_eq!( |
| 98 | + Solution::find_substring( |
| 99 | + "wordgoodgoodgoodbestword".to_string(), |
| 100 | + vec![ |
| 101 | + "word".to_string(), |
| 102 | + "good".to_string(), |
| 103 | + "best".to_string(), |
| 104 | + "word".to_string() |
| 105 | + ] |
| 106 | + ), |
| 107 | + vec![], |
| 108 | + ); |
| 109 | + assert_eq!( |
| 110 | + Solution::find_substring( |
| 111 | + "barfoofoobarthefoobarman".to_string(), |
| 112 | + vec![ |
| 113 | + "bar".to_string(), |
| 114 | + "foo".to_string(), |
| 115 | + "the".to_string(), |
| 116 | + ] |
| 117 | + ), |
| 118 | + vec![6, 9, 12], |
| 119 | + ); |
| 120 | + } |
| 121 | +} |
0 commit comments