力扣leetcode30 串聯所有單詞的子串

2022-02-23 21:15:06 字數 3855 閱讀 4026

和《詳細通俗的思路分析,多解法》解法相同,該文章已經寫得很清晰了,就不再贅述,但是這個演算法處理了很多不必要的位置。因為在最終匹配的解裡面一定含有words[0],那麼先用o(n)時間(可以用kmp)找到所有的可能位置,然後對該位置使用滑動視窗即可,耗時為鏈結中演算法的1/4左右,儘管在leetcode測試中筆者耗時為他的三倍多,但是資料量大才能有效地說明演算法的效率問題

分別在1kw長度,20個words,words[0]長度1000,字元種類50

和1e長度,20個words,words[0]長度10000,字元種類50

下測的的結果,第乙個為筆者的執行時間,單位s

**寫的比較亂,能知道增加部分的含義就行

1

class

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...