
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的长度为Slen, L的长度为Llen, L中每个单词的长度为Lstrlen
把L中的单词排序
首个字符遍历S中的每一个字符
然后以首字符为起点,获取Llen个Lstrlen长度的单词,把获取的单词排序。
比较两个排序后的单词是否相同。相同则压入答案,不同则遍历下一个起点。
时间复杂度为O(Slen*Llen*log(Llen))
结果超时了。分析一下原因:
S: "barfoothefoobarman"
L: ["foo", "bar"]
在遍历第一个起始点时,我们获取了 bar foo
在遍历第4个起始点时,我们获取了 foo the. 但这个foo在遍历第一个起始点时已经遍历过了,故我们做了重复的计算。
------------------------------------------------------------------------------------------------------
下面是大神O(Slen*Lstrlen)的答案
用hash表cn记录每个单词出现的次数
对 i = 0 - Lstrlen 遍历
对 j = i - Slen遍历 ;j+= Lstrlen
获取以j为起点的一个单词。
if(不存在这个单词)
起始位置订到下一个单词起始点,数据清0
else if(存在这个单词,并且出现次数小于cn中统计的次数)
获取的单词数增加
else(存在这个单词,但出现次数大于等于cn中统计的次数)
把起始位置重新定位到这个单词第一次出现之后
if(获取单词数==L中单词数)
压入答案
class Solution {
public:
//超时
vector<int> findSubstring2(string S, vector<string> &L) {
vector<int> ans;
if(L.empty()) //L是空的
{
return ans;
}
int Llen = L.size();
int Slen = S.size();
int Lstrlen = L[].size(); if(Slen < Lstrlen) //S没有L中的字符串长
{
return ans;
} sort(L.begin(), L.end()); for(int i = ; i < Slen - Llen * Lstrlen; i++)//起始位置循环
{
bool isOK = true;
vector<string> cur;
for(int j = ; j < Llen; j++)
{
cur.push_back(S.substr(i + j * Lstrlen, Lstrlen));
}
sort(cur.begin(), cur.end());
for(int j = ; j < Llen; j++)
{
if(cur[j] != L[j])
{
isOK = false;
break;
}
}
if(isOK)
{
ans.push_back(i);
i += Llen * Lstrlen - ;
}
}
return ans;
}
}; //大神可以通过的代码
class Solution2 {
private:
vector<int> res;
map<string,int> cntL;
map<string,int> cn;
int n ;
public:
vector<int> findSubstring(string S, vector<string> &L)
{ res.clear();
cntL.clear();
cn.clear(); n = S.length();
int e = L.size();
int t = L[].length();
int k = ; for(int i = ; i < e ; i++)
{ if(cn.count(L[i]) == )
{ cn[L[i]] = ;
k++;
}
else
{ cn[L[i]] += ;
k++;
}
} string tr ,du;
int r = ;
int st = ; for(int j = ; j < t ; j++)
{ r = ; st = j;
for(int i = j; i < n; i += t)
{ tr = S.substr(i,t);
if( cn.count(tr) == || cn[tr] == )
{ cntL.clear();
r = ;
st = i+t;
}
else if(cntL[tr] < cn[tr])
{ cntL[tr] += ;
r++;
}
else
{ du = S.substr(st,t);
while(du != tr)
{ cntL[du]--;
r--;
st += t;
du = S.substr(st,t);
}
st += t;
}
if(r == k)
{ res.push_back(st);
du = S.substr(st,t);
cntL[du]--;
r--;
st += t;
} }
cntL.clear();
}
sort(res.begin(),res.end());
return res ;
}
};