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] 由小写英文字母组成
通过次数115,443提交次数305,855
思路:
时间复杂度:O(ls*n),空间复杂度O(m*n)
用滑动窗口法,把每一个单词当成一个字母做
代码:
func findSubstring(s string, words []string) []int {
ls,m,n := len(s),len(words), len(words[0])
var res []int
for i:=0;i<n&& i<= ls- m*n;i++{
mp := make(map[string]int, 0)
for j:=0; j<m; j++{
mp[s[i+j*n:i+(j+1)*n]]++
}
for _,v := range words{
mp[v]--
if mp[v] == 0{
delete(mp,v)
}
}
for start:=i; start< ls - m*n+1; start+=n{
if start != i{
mp[s[start-n:start]]--
if mp[s[start-n:start]] == 0{
delete(mp,s[start-n:start])
}
mp[s[start+m*n-n:start+m*n]]++
if mp[s[start+m*n-n:start+m*n]] == 0{
delete(mp,s[start+m*n-n:start+m*n])
}
}
if len(mp) == 0{
res = append(res, start)
}
}
}
return res
}
代码效率:
执行用时:12 ms, 在所有 Go 提交中击败了72.86%的用户
内存消耗:6.5 MB, 在所有 Go 提交中击败了42.65%
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!