LeetCode之串聯所有單詞的子串 30

2021-09-11 11:01:19 字數 4019 閱讀 5562

給定乙個字串 s 和一些長度相同的單詞 words。找出 s 中恰好可以由 words 中所有單詞串聯形成的子串的起始位置。

注意子串要與 words 中的單詞完全匹配,中間不能有其他字元,但不需要考慮 words 中單詞串聯的順序。

示例 1:

輸入: s = 「barfoothefoobarman」, words = [「foo」,「bar」] 輸出:[0,9] 解釋:

從索引 0 和 9 開始的子串分別是 「barfoor」 和 「foobar」 。 輸出的順序不重要, [9,0] 也是有效答案。

示例2:

輸入: s = 「wordgoodgoodgoodbestword」, words =

[「word」,「good」,「best」,「word」] 輸出:

這題的難度是困難。

我第一次做,想到的是暴力解法。即創造乙個words的字典,對字串進行遍歷。擷取一段分割後存入乙個新字典,如果與原字典相同,說明全匹配,新增即可。說起來,不考慮字典花費的時間的話,時間複雜度應該是o(nm)。以下是**

class

solution

:def

make_list

(self,s:

str,n:

int,word:

dict)-

>

bool

: i=

0 joke=

#print(s)

while

(i<

len(s)):

if s[i:i+n]

notin word:

return

false

if s[i:i+n]

in joke:

joke[s[i:i+n]]+=

1else

: joke[s[i:i+n]]=

1 i+=n

return joke==word

deffindsubstring

(self, s:

str, words: list[

str])-

> list[

int]:if

len(words)==0

:return

ifnot words[0]

:return

[i for i in

range

(len

(s)+1)

] word=

joke=

for i in words:

if i in word:

word[i]+=1

else

: word[i]=1

len_of_word=

len(words[0]

)for left in

range

(len

(s))

: right=left+

len(words)

*len_of_word

if self.make_list(s[left:right]

,len_of_word,word)

:return joke

8000多ms,這就太丟臉了,一定有更好的辦法。

改進了一下

這個主要就是對字典的使用進行了改進,不必每次從頭開始新增,而是每次刪去多餘的我們不需要的資料。

class

solution

:def

findsubstring

(self, s:

str, words: list[

str])-

> list[

int]:if

len(words)==0

:return

ifnot words[0]

:return

[i for i in

range

(len

(s)+1)

] word=

ans=

for i in words:

if i in word:

word[i]+=1

else

: word[i]=1

lwd=

len(words[0]

)#len_of_word

lwds=lwd*

len(words)

#len_of_words

for i in

range

(min

(lwd,

len(s)

-lwds+1)

):left=wp=i#word_position

test=

while

(left+lwds<=

len(s)):

w=s[wp:wp+lwd]

wp+=lwd

if w in word:

if w in test:

test[w]+=1

while

(test[w]

>word[w]):

test[s[left:left+lwd]]-=

1 left+=lwd

else

: test[w]=1

else

: left=wp

test.clear(

)if left+lwds==wp:

return ans

再貼乙個方法跟我類似但是時間效率比我好的**吧

執行用時為 64 ms 的範例

class

solution

:def

findsubstring

(self, s, words):if

len(words)==0

:return

lens =

len(s)

lenw =

len(words[0]

) lenws = lenw *

len(words)

if lens < lenws:

return

counter =

for i in

range

(len

(words)):

if words[i]

in counter:

counter[words[i]]+=

1else

: counter[words[i]]=

1 res =

for i in

range

(min

(lenw, lens-lenws +1)

):s_pos = word_pos = i

d =while s_pos + lenws <= lens:

# 擷取單詞

word = s[word_pos:word_pos + lenw]

# 移動到下乙個單詞

word_pos += lenw

if word not

in counter:

s_pos = word_pos

d.clear(

)else

:if word not

in d:

d[word]=1

else

: d[word]+=1

while d[word]

> counter[word]

: d[s[s_pos:s_pos + lenw]]-=

1 s_pos += lenw

if word_pos - s_pos == lenws:

return res

Leetcode初學 串聯所有單詞的子串

我認為這道題要做出來是不難的,主要是怎麼使他的效率變高 可惜我僅僅只是將這道題做出來,深感慚愧 我的思路可以算是滑動窗體吧 因為words中的每個單詞的長度相同,所以我們已知這個長度 以這個長度作為我們窗體的長度,在s中尋找是否有在words中存在的單詞 有的話,刪除words中存在的這個單詞,繼續...

串聯所有單詞的子串

給定乙個字串 s 和一些長度相同的單詞 words。找出 s 中恰好可以由 words 中所有單詞串聯形成的子串的起始位置。注意 子串要與 words 中的單詞完全匹配,中間不能有其他字元,但不需要考慮 words 中單詞串聯的順序。示例 1 輸入 s barfoothefoobarman word...

30 串聯所有單詞的子串 leetcode

好久沒刷題了。今天再刷題記錄下 給定乙個字串 s 和一些長度相同的單詞 words。找出 s 中恰好可以由 words 中所有單詞串聯形成的子串的起始位置。注意子串要與 words 中的單詞完全匹配,中間不能有其他字元,但不需要考慮 words 中單詞串聯的順序。示例 1 輸入 s barfooth...