【题目描述】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).
给你一个字符串,和一个字符串的数组,需要返回一个该字符串的索引组成的数组,返回的索引有如下性质:从每个索引开始,长度为L的字串需要精确包含字符串数组中的所有字符串(不多不少)。L 为字符串数组中所有字符串长度之和。
【解题思路】使用一个map,键为字符串数组中的字符串,值为该字符串在字符串数组中出现的次数。遍历字符串s,寻找和字符串数组中的字符串相同的字串,找到后map中的值减一,否则重新初始化map,从下一个字符开始遍历。如果map中所有的值都为0,则找到了一个符合条件的子串,索引压入数组。
【考查内容】字符串
class Solution {
public:
void initializeMap(map<string,int>& map, vector<string>& words){
for(int i = 0 ;i< words.size();i++){//初始化map
if(map.count(words[i])==0){
map[words[i]] = 1;
}
else
map[words[i]] += 1;
}
}
vector<int> findSubstring(string s, vector<string>& words) {
map<string, int> mapOfVec;
int singleWordLen = words[0].length();//单个字符串长度
int wordsLen = words.size();
int slen = s.length();
int i,j,count;
bool countChanged = false;//判断是否改变过map中的值,如果没变则无需重新初始化
vector<int> result;
count = wordsLen; //一个计数器表示还需要找到的字串个数
if(wordsLen == 0 || slen ==0) return result;
initializeMap(mapOfVec,words);
for(i = 0; i<= slen-wordsLen*singleWordLen;i++){
string subStr = s.substr(i,singleWordLen);// 取出字串
j = i;
while(mapOfVec.count(subStr)!=0 && mapOfVec[subStr]!=0 && j+singleWordLen<=slen){//当该字串存在于map中且值大于0,并且j不越界的情况下
mapOfVec[subStr] -=1; //值减1
count--;
countChanged = true; //改变了map的值
j=j+singleWordLen;
subStr = s.substr(j,singleWordLen); //下一个字串
if(mapOfVec.count(subStr)==0){
break;
}
}
if(count==0){
result.push_back(i); //找齐所有字符串数组中的字串后把该索引压入;
}
if(countChanged){ //若未找到而且改变了map的值需要重新初始化map和count
mapOfVec.clear();
initializeMap(mapOfVec,words);
count = wordsLen;
countChanged = false;
}
}
return result;
}
};