Substring with Concatenation of All Words

Total Accepted: 45534 Total Submissions: 226763 Difficulty: Hard

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in wordsexactly once and without any intervening characters.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> res ;
        
        int s_size     = s.size()    ;
        int words_size = words.size();
        int word_size  = words_size==0 ? 0 : words[0].size();
        
        if(s_size==0 || words_size==0 || s_size< words_size*word_size){
            return res;
        }
        
        /* 把单词装入字典,滑动窗口中的单词需要与字典中的单词进行比较 */
        unordered_map<string,int> dicts;
        for(int i=0;i<words.size();i++){
            dicts[words[i]]++;
        }
        
        int dicts_size = dicts.size();
        
        /* 以下5个变量为滑动窗口的属性 */
        int  win_start        = -1 ;
        int  win_end          = 0 ;
        int  win_size         = words_size * word_size;
        int  win_word_cnt     = 0 ;//滑动窗口中单词的个数,符合要求的滑动窗口,其单词个数与字典中的单词个数是一致的
        unordered_map<string,int> win_words;   
        
        
        for(int index = 0; index < word_size;index++ )
        {
            win_start        = index-1 ;
            win_end          = index ;
            win_word_cnt     = 0 ;
            win_words.clear();
            
            for(int i=index;i<=s_size;i+=word_size){
              
                if(i==index){
                    win_start = index;
                    continue;
                }
                string word = s.substr(i-word_size,word_size);
                win_words[word]++;
                
              //  cout<<"word="<<word<<",win_words["<<word<<"]="<<win_words[word]<<endl;
                
                /* 统计滑动窗口中的单词个数 */
                if(win_words[word]==1){
                    win_word_cnt++;
                }
                win_end = i;
                
                /* 每一个滑动窗口进行判断,看是否符合要求 */
                if(win_end-win_start == win_size){
                  //  cout<<"winstr="<<s.substr(win_start,win_size) << " ,win_start="<<win_start<<",win_end="<<win_end<<",win_word_cnt="<<win_word_cnt<<endl;
                    
                    if(win_word_cnt == dicts_size){
                            bool is_win_satisfied = true;
                        //    cout<<"--------------------------"<<endl;
                            for(int j=win_start;j<win_end;j+=word_size){
                                string win_word = s.substr(j,word_size);
                             //   cout<<"dicts["<<win_word<<"]="<<dicts[win_word]<<",win_words["<<win_word<<"]="<<win_words[win_word]<<endl;
                                if(dicts[win_word]==0 || win_words[win_word] != dicts[win_word]){
                                    is_win_satisfied   = false;
                                    break;
                                }
                            }
                            if(is_win_satisfied){
                                res.push_back(win_start);
                            }
                    }
                    
                    
                    /* 滑动窗口下移一个位置,更新窗口内的单词数量 */
                    string win_word = s.substr(win_start,word_size);
                    win_words[win_word]--;
                    if(win_words[win_word]==0){
                        win_word_cnt--;
                    }
                    win_start += word_size;
                }
            }
        }
        return res;
    }
};
 
原文地址:https://www.cnblogs.com/zengzy/p/5042650.html