給定乙個字串 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...