[Leetcode] Substring with concatenation of all words 串联所有单词的子串

You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.

For example, given:
S:"barfoothefoobarman"
L:["foo", "bar"]

You should return the indices:[0,9].
(order does not matter).

题意:给定一字符串S,几个长度相同的单词,让我们找到串联单词的所有起始位置,单词串中,单词串联的顺序不管,且之间都没有空格每个单词串只出现一次。

与题目解答无关:我是把题目做完一遍以后,再在博客上进行整理的,结果发现这道题一下子没有想出来,看以前的做过的答案,才把思路理清楚的,但是很尴尬的是,不知道以前是不是我自己做出来的,很大可能上不是,这道题的参考网站也恰好没有留下记录,所以要是大伙知道这题的原出处,跟我说一声,我标明引用哈。

思路:这道题用到两个哈希表,第一个哈希表先把所有的单词放进去。然后从头开始遍历目标串S(跳出循环的条件是,当S中剩下的字符个数小于L中单词总的长度时),针对每个字符 i,都以其为起始点在目标串S中取长度为m(单个单词的长度),循环的总长度是n*m(L中单词的总长度)放入第二个哈希表中,然后看S中的这个长度为m的单词是否在单词串L存在,若存在,还要继续考虑相同单词是否仅出现一次,如果多了,也跳出循环。这里给出了更多解释,代码如下:

 1 class Solution {
 2 public:
 3     vector<int> findSubstring(string S, vector<string> &L) 
 4     {
 5         vector<int> res;
 6         if(S.empty() || L.empty())  return res;
 7        
 8         unordered_map<string,int> m1;
 9         for(auto &a:L)
10             m1[a]++;
11 
12          int n=L.size(),m=L[0].size(),len=S.size();
13 
14         for(int i=0,j;i<=len-n*m;++i)
15         {
16             unordered_map<string,int> m2;
17           
18             for(j=i;j<i+n*m;j+=m)
19             {
20                 string tem=S.substr(j,m);
21                 m2[tem]++;
22                 if( !m1.count(tem) || m2[tem] > m1[tem])
23                     break;
24             }
25             if(j>=i+m*n)
26                 res.push_back(i);
27         }    
28         return res;
29     }
30 };

 这里用两个unordered_map是因为,只有一个,无法判断类似barbar的非法性。