题目
30. 串联所有单词的子串
给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。
示例 1 :
输入:s = "barfoothefoobarman" , words = [ "foo" , "bar" ]
输出:[ 0 , 9 ]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [ 9 , 0 ] 也是有效答案。
示例 2 :
输入:s = "wordgoodgoodgoodbestword" , words = [ "word" , "good" , "best" , "word" ]
输出:[ ]
示例 3 :
输入:s = "barfoofoobarthefoobarman" , words = [ "bar" , "foo" , "the" ]
输出:[ 6 , 9 , 12 ]
提示:
1 <= s. length <= 104
s 由小写英文字母组成
1 <= words. length <= 5000
1 <= words[ i] . length <= 30
words[ i] 由小写英文字母组成
方法1:哈希+比较
public List < Integer > findSubstring ( String s, String [ ] words) {
Map < String , Integer > dict = new HashMap < > ( ) ;
int len = 0 , w_len = 0 ;
for ( String word : words) {
len += word. length ( ) ;
w_len = word. length ( ) ;
dict. put ( word, dict. getOrDefault ( word, 0 ) + 1 ) ;
}
int n = s. length ( ) ;
List < Integer > res = new ArrayList < > ( ) ;
for ( int i = 0 ; i + len - 1 < n; i++ ) {
Map < String , Integer > can = new HashMap < > ( ) ;
String sub = s. substring ( i, i + len) ;
for ( int j = 0 ; j < len; j += w_len) {
String seg = sub. substring ( j, j + w_len) ;
can. put ( seg, can. getOrDefault ( seg, 0 ) + 1 ) ;
}
if ( dict. equals ( can) ) {
res. add ( i) ;
}
}
return res;
}