LeetCode/串联所有单词的子串
给定一个字符串 s 和一些长度相同的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。
1. 暴力匹配
显然,与所有单词匹配的子串长度必然等于所有单词的长度和,所有只需滑动窗口进行匹配即可
匹配时候要注意子串是由单词任意顺序拼接的,所以可以用到哈希表结构
对所有单词进行评估,得到一个无序哈希表,然后对子串评估得到另一个哈希表,比较两哈希表是否相同
若相同将此事窗口起始位置存入结果中
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> ret;//用于存储最后结果
if(words.size() == 0)
return ret;//返回空集
int word_size = words[0].size();//记录每个单词长度
int word_num = words.size();//记录单词数量
unordered_map<string,int> m1;//构造所有单词的hashmap
for(int i=0;i<word_num;i++)
m1[words[i]]++;
unordered_map<string,int> m2;//构件评估子串的hashmap
for(int i=0; (i + words_size ) <= s.size() ; i++){//窗口滑动
int j;//这里要在循环外面定义,用于最后判断是否匹配成功
for(j=i;j < (i + words_size ) ; j=j+word_size){//分单词判断
string temp_str = s.substr(j,word_size);//截取单词
if(m1[temp_str] == 0){//m1中没有截取的串,直接跳出
break;
}else{
m2[temp_str]++;
if(m1[temp_str] < m2[temp_str])//重复次数过多,也跳出
break;
}
}
if(j == (i + word_size * word_num))//每一段都符合,则加入答案
ret.push_back(i);
m2.clear();//清空m2,用于下一次比较
}
return ret;
}
};