30.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package main
  2. func findSubstring(s string, words []string) []int {
  3. indices := []int{}
  4. strLen, wordCnt := len(s), len(words)
  5. if strLen == 0 || wordCnt == 0 {
  6. return indices
  7. }
  8. dict := make(map[string]int) // May contains duplicate words!
  9. for _, word := range words {
  10. dict[word]++
  11. }
  12. wordLen := len(words[0])
  13. for i := 0; i < wordLen; i++ {
  14. left, count := i, 0
  15. occur := make(map[string]int)
  16. for j := i; j <= strLen-wordLen; j += wordLen {
  17. word := s[j : j+wordLen]
  18. // If word is valid, accumulate results
  19. if _, ok := dict[word]; ok {
  20. occur[word]++
  21. if occur[word] <= dict[word] {
  22. count++
  23. } else {
  24. // One more word occur, shift the left side of window
  25. for occur[word] > dict[word] {
  26. leftWord := s[left : left+wordLen]
  27. occur[leftWord]--
  28. if occur[leftWord] < dict[leftWord] {
  29. count--
  30. }
  31. left += wordLen
  32. }
  33. }
  34. // Come to a result
  35. if count == wordCnt {
  36. indices = append(indices, left)
  37. // Advance left side by one word
  38. occur[s[left:left+wordLen]]--
  39. count--
  40. left += wordLen
  41. }
  42. } else {
  43. // Not in word dict, reset all
  44. occur = make(map[string]int)
  45. count = 0
  46. left = j + wordLen
  47. }
  48. }
  49. }
  50. return indices
  51. }
  52. // func main() {
  53. // fmt.Println(findSubstring(
  54. // "wordgoodgoodgoodbestword",
  55. // []string{"word", "good", "best", "good"}))
  56. // fmt.Println(findSubstring(
  57. // "foobarfoobar",
  58. // []string{"foo", "bar"}))
  59. // }