和《詳細通俗的思路分析,多解法》解法相同,該文章已經寫得很清晰了,就不再贅述,但是這個演算法處理了很多不必要的位置。因為在最終匹配的解裡面一定含有words[0],那麼先用o(n)時間(可以用kmp)找到所有的可能位置,然後對該位置使用滑動視窗即可,耗時為鏈結中演算法的1/4左右,儘管在leetcode測試中筆者耗時為他的三倍多,但是資料量大才能有效地說明演算法的效率問題
分別在1kw長度,20個words,words[0]長度1000,字元種類50
和1e長度,20個words,words[0]長度10000,字元種類50
下測的的結果,第乙個為筆者的執行時間,單位s
**寫的比較亂,能知道增加部分的含義就行
1class
solution(object):
2def
findsubstring(self, s, words):3if
notwords:
4return
5ifnotwords[0]:
6return [i for i in range(len(s) + 1)]
7if len(s) < len(words) *len(words[0]):
8return
910 set_word ={}
11for i in
words:
12if i in
set_word:
13 set_word[i] += 1
14else
:15 set_word.update()
16 len_word =len(words[0])
17 len_s =len(s)
18 words_num =len(words)
1920 arry =
21 index =s.find(words[0])
22while index != -1:
2324 index = s.find(words[0], index + 1)25#
print(arry)
2627 ans =set()
28 next_start = -1
29for num in
arry:
30 start = num - len_word * (words_num - 1)
31if num >= next_start - 1:
32 ans_temp, next_start =self.is_match(s, set_word, len_word, len_s, words_num, start, num)
33 ans |=ans_temp
3435
#print(list(ans))
36return
list(ans)
3738
defis_match(self, s, set_word, len_word, len_s, words_num, start, end):
39 ans =set()
40 offset =0
41 cache =set_word.copy()
42 word_list =
43 next_start = -1
44while start + (words_num - len(word_list)) * len_word <= len_s and start <= end + len(word_list) *len_word:
45if start >=0:
46 same =0
47for i in range(words_num -len(word_list)):
48 this_word = ""
49for j in
range(len_word):
50 this_word += s[start + i * len_word +j]
51if this_word in
cache:
52if cache[this_word] >0:
5354 cache[this_word] -= 1
55elif this_word ==word_list[0]:
56 same = 1
57 start += len_word *len(word_list)
58 offset = len_word * (len(word_list) - 1)
59word_list.pop(0)
60 cache[this_word] += 1
61break
62else:63
break
64else:65
break
6667
ifnot
same:
68 flag =0
69for i in
cache:
70if cache[i] >0:
71 flag = 1
72break
73if
flag:
74if
word_list:
75for i in
range(len(word_list)):
76 start +=len_word
77 this_word =word_list.pop(0)
78 cache[this_word] += 1
79else
:80 start +=len_word
81 cache =set_word.copy()
82 offset =0
83else
:84 ans.add(start -offset)
85 start += len_word *words_num
86 offset = len_word * (words_num - 1)
87 this_word =word_list.pop(0)
88 cache[this_word] += 1
89 next_start = start -offset
90else
:91 start +=len_word
92return ans, next_start
力扣 LeetCode 30 串聯所有單詞的子串
給定乙個字串 s 和一些長度相同的單詞 words。找出 s 中恰好可以由 words 中所有單詞串聯形成的子串的起始位置。注意子串要與 words 中的單詞完全匹配,中間不能有其他字元,但不需要考慮 words 中單詞串聯的順序。示例 1 輸入 s barfoothefoobarman words...
leetcode 30 串聯所有單詞的子串
leetcode題目鏈結 題目要求 找出 由words陣列組成的字串 每乙個元素word等長 在字元轉s中的位置 陣列words生成的字典dic2 遍歷字串,從頭開始判斷長度為lenwords的字串 生成的字典dic1 如果dic1 與 dic2 相同,說明找到 def findsubstring ...
leetcode 30 串聯所有單詞的子串
給定乙個字串 s 和一些長度相同的單詞 words。找出 s 中恰好可以由 words 中所有單詞串聯形成的子串的起始位置。注意子串要與 words 中的單詞完全匹配,中間不能有其他字元,但不需要考慮 words 中單詞串聯的順序。示例 1 輸入 s barfoothefoobarman words...