12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- package main
- func findSubstring(s string, words []string) []int {
- indices := []int{}
- strLen, wordCnt := len(s), len(words)
- if strLen == 0 || wordCnt == 0 {
- return indices
- }
- dict := make(map[string]int) // May contains duplicate words!
- for _, word := range words {
- dict[word]++
- }
- wordLen := len(words[0])
- for i := 0; i < wordLen; i++ {
- left, count := i, 0
- occur := make(map[string]int)
- for j := i; j <= strLen-wordLen; j += wordLen {
- word := s[j : j+wordLen]
- // If word is valid, accumulate results
- if _, ok := dict[word]; ok {
- occur[word]++
- if occur[word] <= dict[word] {
- count++
- } else {
- // One more word occur, shift the left side of window
- for occur[word] > dict[word] {
- leftWord := s[left : left+wordLen]
- occur[leftWord]--
- if occur[leftWord] < dict[leftWord] {
- count--
- }
- left += wordLen
- }
- }
- // Come to a result
- if count == wordCnt {
- indices = append(indices, left)
- // Advance left side by one word
- occur[s[left:left+wordLen]]--
- count--
- left += wordLen
- }
- } else {
- // Not in word dict, reset all
- occur = make(map[string]int)
- count = 0
- left = j + wordLen
- }
- }
- }
- return indices
- }
- // func main() {
- // fmt.Println(findSubstring(
- // "wordgoodgoodgoodbestword",
- // []string{"word", "good", "best", "good"}))
- // fmt.Println(findSubstring(
- // "foobarfoobar",
- // []string{"foo", "bar"}))
- // }
|