给一个string S和一个vector<string> L,L中是等长的字符串。寻找S的满足以下条件的子串:该子串是L中的所有string(每个string只能出现一次)的连接,返回字串的位置。如 S: "barfoothefoobarman"
L: ["foo", "bar"],返回结果[0,9]

这道题我最初的想法是两个循环,首先对开始位置beg在[0,Slength-cnt*len)]遍历(其中Slength表示S的长度,cnt表示L中string的个数,len表示每个字符串的长度),之后对一beg开头的长度为cnt*len的子串进行遍历,把遍历过的L中的元素下标相加。如果满足条件,则整数应为n(n-1)/2.如果不等,则该字串不满足条件。

测试错误,主要是没有考虑到L中存在相同元素的可能性。

改进算法,使用map<string,int>,首先保存L中每个元素出现的个数。之后同样的方法遍历S,查找字串,是子串中包含了map中的所有元素请元素出现次数相同。

测试超时

原来的遍历对某些字串遍历了多遍,导致时间复杂度过高。如果L中元素长度为3,则以0为开头的遍历过程中,会找到字串[0,3),[3,6),[7,9)...等,之后再以3为开头的遍历中,会重新遍历[3,6),[6,9)等,所以改进算法。采用类型窗口滑动的方式进行遍历,一个窗口的长度为3,代码如下:

 1 class Solution {
 2 public:
 3     vector<int> findSubstring(string S, vector<string> &L) 
 4     {
 5         vector<int> result;
 6         int Slen=S.size();
 7         int cnt=L.size();
 8         int len=L[0].size();
 9         if(Slen<len)
10         {
11             return result;
12         }    
13         map<string,int> lmap;
14         map<string,int> tmap;        
15         for(size_t i=0;i<cnt;i++)
16         {
17             if(lmap.find(L[i])==lmap.end())
18             {
19                 lmap[L[i]]=1;
20             }
21             else
22             {
23                 lmap[L[i]]+=1;
24             }
25         } 
26         for(size_t i=0;i<len;i++)
27         {
28             size_t beg=i;
29             for(size_t j=i;j<=(Slen-len);j+=len)
30             {
31                 string temp=S.substr(j,len);
32                 if(lmap.find(temp)==lmap.end())
33                 {
34                     tmap.clear();
35                     beg=j+len;
36                     continue;
37                 }
38                 else if(tmap.find(temp)==tmap.end())
39                 {
40                     tmap[temp]=1;
41                 }
42                 else 
43                 {
44                     tmap[temp]+=1;
45 
46                 }
47                 if(tmap[temp]==lmap[temp])
48                 {
49                     if(j-beg==(cnt-1)*len)
50                     {
51                         result.push_back(beg);
52                         tmap[S.substr(beg,len)]--;
53                         beg+=len;
54                     }
55                 }
56                 if(tmap[temp]>lmap[temp])
57                 {
58                     int k=beg;
59                     for(;k<=j;k++)
60                     {
61                         if(S.substr(k,len)==temp)
62                         {
63                             break;
64                         }
65                     }
66                     beg=k+len;
67                     tmap[temp]--;
68                 }
69             }
70             tmap.clear();
71         }
72         return result;
73     }
74 };