去找一个字符串包含L中所有单词的拼接组合的子串的下标。需要注意:L中的单词可重复!
大致思路:
就是遍历起点i,然后依次去匹配,必须把L中的单词都连续匹配完而且都只出现1次(考虑到L中的单词可重复,就转化为——在子串中出现的单词次数要==在L中该单词出现的次数,用两个map数组来比较)。
编程上,求子串用到了str.substr(起点下标,长度),注意第二个参数是长度,我之前弄成终点下标了。。要和find函数区别开!另外,求是否在vector中出现过使用了count(vec.begin(),vec.end(),target)
具体看懂程序和注释就OK。
AC代码:
class Solution {
public:
vector<int> findSubstring(string S, vector<string> &L) {
//还是只看字母的出现次数
int lenS= S.size();
int lenL= L.size();
vector<int> res;
if(lenS==0)
return res;
if(lenL==0)
return res;
map<string,int> v; //记录每个单词在L中出现的次数
for(int i=0;i<lenL;i++)
v[L[i]]=0;
for(int i=0;i<lenL;i++)
v[L[i]]++;
map<string,int> m; //记录每个单词在不同的子串中出现的次数
int len = L[0].size(); //单词的长度(题意:每个单词长度一样)
for(int i=0;i<=lenS-len*lenL;i++)
{
//初始化
for(int i=0;i<lenL;i++)
m[L[i]]=0;
//以i为起点,来看len*lenL长度的子串是否包含了lenL个单词且每个单词只出现一次
int j;
for(j=0;j<lenL;j++) //有lenL个单词要匹配
{
int start = i+j*len;
//对每一个单词都看看对的上不
string thisWord = S.substr(start,len); //注意str.substr(起点下标,长度)
if(count(L.begin(),L.end(),thisWord)!=0)
{
m[thisWord]++;
if(m[thisWord]>v[thisWord]) //出现得比在L中出现的次数更多 不对
break;
}
else //都找不到
break;
}
if(j==lenL) //表示都匹配完了,以i为起点符合要求。注意最后j还会有一次自增所以==lenL
res.push_back(i);
}
return res;
}
};