1.题目
题目分析:
有一个字符串s和字符串数组,如何字符串数组里面的元素可以组成一个字符串,然后要在字符串里面找到连续子串跟组成的字符串一样,返回起始地址。
2.算法原理
这道题可以把字符串数组的元素string看出char,把字符串里面也按照大小合成一个字母,也就是说n个字母组成的单词在字符串里面找连续子串,就可以用异位词的方法处理,用哈希表来存储,string表示字符,int表示出现的次数,先把字符串数组的元素放到哈希表,然后开始进窗口,用substr函数把多个字符一起读取,放入第二个哈希表中,比较是否大于第一个哈希表这个字符出现的次数,小于说明是第一次出现就可以把count++,当界限大于字符串数组元素总长时,就要开始出窗口了,向判断次数在--,避免把种类减少了。
注意,上面的情况是按照从开头开始切分,但有时不是开头,而是第二个第三个,前面都是无效字符,所以就需要在来一次for循环,次数是字符串数组的单个元素的大小,这样就可以遍历所有情况了。
3.代码实现
优化操作,hash1[in]和hash2[out]有可能会插入新元素,因为都是未出现的,就会开辟空间去存放新元素,造成空间损耗。
class Solution {
public:vector<int> findSubstring(string s, vector<string>& words) {vector<int> result;unordered_map<string,int> hash1;//unordered_map<string,int> hash2;for(auto& s:words) hash1[s]++;int len=words[0].size(),m=words.size();for(int i=0;i<len;i++){unordered_map<string,int> hash2;for(int left=i,right=i,count=0;right+len<=s.size();right+=len){string in =s.substr(right,len);hash2[in]++;if(hash1.count(in)&&hash2[in]<=hash1[in]) count++;if(right-left+1>len*m){string out=s.substr(left,len);if(hash1.count(out)&&hash2[out]<=hash1[out]){count--;}hash2[out]--;left+=len;}if(count==m) result.push_back(left);}}return result;}
};