赞
踩
难度:困难
给定一个字符串 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]
由小写英文字母组成链接: 30. 串联所有单词的子串
这题是 438. 找到字符串中所有字母异位词的加强版,区别是单位从字母变成单词。都可以用滑窗做。
words
中每个单词长度相同,设为d,只需要控制滑窗右移时,每次移动d个字母即可,也就是删去一个单词,纳入一个单词。words
相同的话就是满足题意的情况。最坏时间复杂度O(n×d),n是s长度,d是word中单词长度
滑动窗口
。
class Solution: def findSubstring(self, s: str, words: List[str]) -> List[int]: wc = Counter(words) n = len(s) m = len(words) d = len(words[0]) if n < d*m: return [] ans = [] for start in range(d): cnt = Counter() i=j = start while j < d*m: cnt[s[j:j+d]] += 1 j += d if cnt == wc: ans.append(start) for j in range(j,n,d): if j+d>n: break cnt[s[j:j+d]] += 1 l = s[i:j-d*m+d] cnt[l] -= 1 if cnt[l] == 0: del cnt[l] # print(j,cnt) i += d if cnt == wc: ans.append(i) return ans
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。