文章目录:
- 题目
- 脚本一
- 脚本一逻辑
- 脚本二
- 脚本二逻辑
题目:
给定一个字符串 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"]
输出:[]
脚本一:【用时:2300ms】
class Solution: def findSubstring(self, s: str, words: List[str]) -> List[int]: try: leng1 = len(words[0]) except IndexError: return([]) leng1 = len(words[0]) leng2 = len(s) leng3 = len(words) leng4 = words.count(words[0]) num1 = leng1 * leng3 try: str_1 = s[0] * leng2 except IndexError: return([]) list1 = words[:] list2 = [] flag1,flag2,flag3 = 1,1,1 if str_1 == s: flag1 = 0 if leng3 == leng4: flag2 = 0 if words[0] in s: flag3 = 0 if flag1 == 0 and flag2 == 0 and flag3 == 0: result = leng2 - num1 + 1 list2 = list(range(result)) return(list2) i = 0 k = 0 while True: j = i + leng1 str1 = s[i:j] if str1 in list1: list1.remove(str1) i += leng1 if not list1: list2.append(k) k += 1 i = k list1 = words[:] else: k += 1 i = k list1 = words[:] if i > leng2: return(list2)
脚本一逻辑:
- 此题是笔者想到的解法,可以规类为暴力破解,原脚本是超时的;但笔者根据leetcode的超时反馈,做了一些调优
- 脚本的基本逻辑如下:
- 比如长字符串str为abbcc,words组合为[aa,bb]
- 第一步:先在长字符串str获取长度为2的短字符串str1为"ab"(aa的长度为2),由于"ab"不在words中,所以长字符串获取点由0加1变为1
- 第二步:再获取长度为2的短字符串bb,由于bb在words中,则剔除words中的该元素,则words变为[aa]
- 第三步:再获取长度为2的短字符串aa,由于aa在words中,则剔除words中的此元素,则words变为[]
- 第四步:如果words变为空,则返回最新开始的取点位,如本例中的1,并将1添加到空列表中
- 重复
脚本二:【用时:870ms 转载】
class Solution: def findSubstring(self, s: str, words: List[str]) -> List[int]: res = [] write = [] if len(words) == 0: return [] if len(s) < len(words)*len(words[0]): return [] dic = {} flag = 0 for i in words: try: dic[i]+=1 except KeyError: dic[i]=1 flag+=1 write.append(i) #是否存在用字典查看 left, right = 0, len(words)*len(words[0]) #滑动窗口 while right<=len(s): n,start = 0,left per = len(words[0]) tag = dict(zip(write,[0]*flag)) while n < len(words): #若存在于字典中 if dic.get(s[start:start+per]): if tag[s[start:start+per]] < dic[s[start:start+per]]: tag[s[start:start+per]] += 1 n+=1 start+=per else: break else: break if n == len(words): res.append(left) left+=1 right+=1 return res
脚本二逻辑:
- 第一:对明显不符合的情况进行排除,比如子串列表为空,或者子串总长度比字符串s还要长
- 第二:创建两个字典dic、tag和一个列表res,其中dic记录子串列表words中的信息,words中每个元素作为字典的键,元素个数作为字典的值;每次进行最外层循环时,tag循环都会恢复原样,原样为已words列表作为字典的键,以0作为值
- 第三:每次进行主循环时,以长字符串的某个字符为起点,进入次循环;若次循环中满足条件则记录结果的空列表增加起点字符的索引值后,起点索引值自增1,进入主循环;若次循环条件不满足,则起点索引值自增1并再次进入主循环;直到未遍历的长字符串字符数小于words所有元素总长度