You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in wordsexactly once and without any intervening characters.
For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]
You should return the indices: [0,9]
.
(order does not matter).
it will take O(n) space and O(kmn) time n is s length k is word length m is words length
class Solution(object):
def findSubstring(self, s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
result = []
if not words:
return result
word_length = len(words[0])
words_length = len(words)
s_length = len(s)
word_hash = {}
for word in words:
if word in word_hash:
word_hash[word] += 1
else:
word_hash[word] = 1
for index in range(word_length):
left_index = index
count = 0
sub_hash = {}
# sliding window
for slide_index in xrange(index, s_length - word_length + 1, word_length):
new_word = s[slide_index : slide_index + word_length]
#check valid word
if new_word in word_hash:
if new_word in sub_hash:
sub_hash[new_word] += 1
else:
sub_hash[new_word] = 1
count += 1
# move index to first none duplicate word
#"wordgoodgoodgoodbestword"
# ["word","good","best","good"] move to index 8 instead of 4
while sub_hash[new_word] > word_hash[new_word]:
sub_hash[s[left_index:left_index + word_length]] -= 1
count -= 1
left_index += word_length
if count == words_length:
result.append(left_index)
else:
count = 0
sub_hash = {}
left_index = slide_index + word_length
return result