难度困难574
给定一个字符串
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]
由小写英文字母组成通过次数86,526提交次数239,367
我的分析:
暴力解决
- 第一层循环是提供内层循环的起始位置,超出长度则跳出
- 第二层循环直接搜索查找words在源字符串当中的下标
- 判断:只有当找到的字符串下标是可以串联起来的,那么就是符合要求
- 列表设计:内层循环的字符串包含了字符串的起始位置和该字符串的长度,外层循环的列表就是保存符合要求的字符串的其实位置
- 缺点:不好处理words当中的重复字符串
我的代码:
def findSubstring(s, words):
start = 0
len_s = len(s)
ls_out = []
while start < len_s:
next = len_s
t = 0
ls_in = []
#开始寻找words最近匹配的下标
for i in range(len(words)):
index = s[start:].find(words[i])
if index < 0 :
start = len_s
break;
if index < next:
next = index
t = i
ls_in.append([start + index,len(words[i])])
#如果都找到元素,继续
if start < len_s:
#判断该列表是否符合题目要求,如果符合,就加入到结果的列表中
ls_in.sort()
flag = True
for i in range(len(words)-1):
#当有重复的words需要特殊处理一下
if ls_in[i][0] + ls_in[i][1] != ls_in[i+1][0]:
flag = False
if flag:
ls_out.append(ls_in[0][0])
start += next + ls_in[t][1]
print(ls_in)
#print(ls_out)
return ls_out
运行结果:
参考代码:
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
wordnum = len(words)
wordlenth = len(words[0])
words = sorted(words)
ans = list()
def issub(string):
#print(string)
tmp = list()
for i in range(0,len(string),wordlenth):
tmp.append(string[i:i+wordlenth])
tmp = sorted(tmp)
if tmp == words:
return True
else:
return False
for i in range(len(s)-wordnum*wordlenth+1):
if issub(s[i:i+(wordnum*wordlenth)]) == True:
ans.append(i)
return ans
运行结果:
思路分析:
其实也是暴力求解的方法时间复杂度也是O(n*n)
- 先对原来字符串进行截取对应长度
- 再用截取字符串跟words进行匹配