Problem
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 words exactly once and without any intervening characters.
Example 1:
1 |
|
Example 2:
1 |
|
Explanation 1
-
Create a hash table and store the
words
frequency. -
Loop through the string
s
, because we need to record the starting index, then we need to create a copy of thei
index astempInd
. For example, get the substringbar
and check if it is in the the hashmap. -
If the substring is not inside the hashmap, then we move the index
i
to the next index. If it is in the hashmap, then we subtract 1 from it’s frequency. If it’s frequency is 0, we can remove its key. ThentempInd += wordLen
, and get the next substringfoo
and check if inside the hashmap, if it is, then do the same thing, reduce its frequncy, if its frequency is 0, remove its key. -
When the hashmap is empty, that means we found all words continuously, and we add the index
i
to theres
list.
Solution 1
1 |
|
Explanation 2
-
We can iterate word by word in this method. From example 1, each word has length 3, then the iteration order will be 0, 3, 6, 8, 12, 15, then moving one steps forward, 1, 4, 7, 9, 13, 16, then moving one steps forward, 2, 5, 8, 10, 14, 17. In this way, we can consider all cases.
-
We need a hashmap
hm
to record the word frequency. Then, we starts from 0, usingleft
to record the starting index, usingcount
to check how many word we have matched so far, usingtempHm
to record the word frequency we have seen so far. -
Iterating word by word, if the word iterated is inside
hm
, then we put inside totempHm
. If the word frequency insidetempHm
is less or equal to the frequency inhm
, then we add one to thecounter
. -
If the word frequency inside
tempHm
is greater than frequency inhm
. For example,s = barfoofoo
,word = {bar, foo, abc}
, when we iterate to the secondfoo
ins
, we havetempHm[foo] = 2
, which is greater thanhm[foo] = 1
, and now theleft
is at index 0. Then, we need to moveleft
pointing to the beginning of the next word, which is at index 3, and we need to remove the first wordbar
out oftempHm
, which means we subtract its frequency by 1. After subtracting its frequency, iftempHm[bar] < hm[bar]
, that means we we lost 1 match, so we subtractcounter
by 1. Again, now theleft
is at index 3 pointing at the firstfoo
ins
. We know that 3 cannot be the correct starting index becausefoofoo
doesn’t matchword
’s frequency. So, we move theleft
pointing to the next word, pointing to the secondfoo
which at index 6, remove the first wordfoo
out oftempHm
, subtract its frequency by 1. Now,temp[foo] == hm[foo]
andleft
is pointing to the correct index, and we contnue the loop. -
If
count == words.length
, then it means we successfully match allwords
continuously, and we store theleft
intores
list. And we remove the first word fromtempHm
and subtractcount
by 1, and move theleft
to pointing at the next word, and continue the loop. -
If the word we iterated is not inside
hm
, for example,s = barxxxfoo
,word = {bar, foo, abc}
becausexxx
is not insidehm
, we move theleft
to index 6 pointing tofoo
and we clear thetempHm
andcount
.
Solution 2
1 |
|