# 30. Substring with Concatenation of All Words

**<font color=red>难度: Hard</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/

> 内容描述

```

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:

Input:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.
Example 2:

Input:
  s = "wordgoodstudentgoodword",
  words = ["word","student"]
Output: []
```

## 解题方案

> 思路 1
******- 时间复杂度: O(word_len * N)******- 空间复杂度: O(word_len)******


把words里面的word和其频率都记下来，然后对s做双指针记录，只要匹配上了words就append到res中去

但是由于从不同起点开始结果不一样，所以最前面还要做一个for循环```for i in range(word_len):```这样从每个起点开始都能到达最后

比如说：

``` 
s = “barfoothefoobarman"
words = ["foo","bar"]

从‘b’出发
从‘a’出发
从‘r’出发

这三种都不一样

比如从'a'出发可以有'arf'，其他点出发就没有这个word

那为什么只有3个起点呢，因为words里面word的长度都是3
```

beats 88.44%


```python
class Solution(object):
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        if len(words) == 0 or len(s) < len(words) * len(words[0]):
            return []
        
        res, n, m, word_len = [], len(s), len(words), len(words[0])
        maps = collections.Counter(words)
        
        for i in range(word_len):
            cur_map, count, start, cur = {}, 0, i, i
            while cur + word_len <= n:
                cur_str = s[cur:cur+word_len]
                if cur_str in maps:
                    cur_map[cur_str] = cur_map.get(cur_str, 0) + 1     
                    if cur_map[cur_str] <= maps[cur_str]:
                        count += 1
                    while cur_map[cur_str] > maps[cur_str]:
                        begin_str = s[start:start+word_len]
                        cur_map[begin_str] -= 1
                        start += word_len
                        if cur_map[begin_str] < maps[begin_str]:
                            count -= 1
                    if count == m:
                        res.append(start)
                        begin_str = s[start:start+word_len]
                        cur_map[begin_str] -= 1
                        start += word_len
                        count -= 1
                else:
                    cur_map, count, start = {}, 0, cur + word_len
                cur += word_len
                
        return res
```






