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;
    }
};
posted @ 2022-06-23 14:01  失控D大白兔  阅读(29)  评论(0编辑  收藏  举报