Substring with concatenation of all words--Problem Solving report (Window Move method)

Source: Internet
Author: User


Topic

You is given a string, s, and a list of words, words, that is all of the same length. Find all starting indices of substring (s) in s that's 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).


Analysis

The solution of this topic has two, the first one is the conventional idea, the second is the window movement method, this method needs to master.


Solution One: First the words exists in a map, key is the word string, value is the number of occurrences. Then iterate through the string s (note that the end of the traverse does not have to be final, the remaining length is less than the total length of the word), and determine whether each word in the substring after it is the same as the total length of the words. If the same, this push_back go in; otherwise, traverse the next character. Time complexity: O (LNW), L is the length of S, N is the number of words, w is the length of word.

Code:

Class Solution {public:vector<int> findsubstring (string s, vector<string>& words) {vector <        int> Res; int N = Words.size ();        Number of words if (N = = 0) return res;  int len = Words[0].length ();  Length of each word int strLen = s.length ();  Length of String map<string, int> countwords;                Get the WordCount map for (int i = 0; i < N; i + +) {if (Countwords.count (Words[i]))            countwords[words[i]]++;        else Countwords[words[i]] = 1;        } map<string, int> counting;            for (int i = 0; I <= strlen-len * N; i++)//First loop {counting.clear ();            BOOL flag = TRUE;                for (int j = i; j < i + N*len; j + = len)//second loop {string w = S.substr (j, Len); if (Countwords.count (w) = = 0)//If not exist in CountWords, breakdirectly {flag = false;                Break } else {if (Counting.count (w))//If not new Coun                    ting[w]++;                else counting[w] = 1;            }} if (!flag) continue;                else {if (compare (counting, countwords)) res.push_back (i);            else continue; }}} bool Compare (map<string, int> counting, map<string, int> countwords) {ma        P<string, Int>::iterator iter; for (iter = Countwords.begin (); ITER! = Countwords.end (); iter++) {if (Counting[iter->first]! = iter-&        Gt;second) return false;    } return true; }};


Solution Two: Window moving method.

First, initialize a window with a length of 0, defining that the head is begin and the tail is tail. Judge Tail after a word, if in the words inside, then tail move backward, that is, the window extends the amount of a word; if the tail behind the word is not in words at all, then move the begin to the last position, reinitialize the window, and continue to judge If the word after tail has appeared before, but there is no capacity for the word in words, then begin to move to the position where the word first appears and continue to judge. The time complexity of this method is O (Lw).

Code:

Class Solution {public:vector<int> findsubstring (String S, vector<string> &l) {UNORDERED_MAP&L T;string, the number of occurrences of a word in int>wordtimes;//l for (int i = 0; i < l.size (); i++) if (Wordtimes.count (l[i]) = =            0) Wordtimes.insert (Make_pair (L[i], 1));        else wordtimes[l[i]]++;                 int wordlen = L[0].size ();        vector<int> Res; for (int i = 0; i < Wordlen; i++) {//In order not to omit substrings starting from each position in S, the first layer loops for the length of the word unordered_map<string, Int>wo rdtimes2;//the number of occurrences of a word in the current window int winstart = i, cnt = 0;//winstart is the starting position of the window, CNT is the number of words in the current window for (int winend = I Winend <= (int) s.size ()-wordlen;                Winend+=wordlen) {//window for [winstart,winend] string word = S.substr (winend, Wordlen); if (wordtimes.find (word) = Wordtimes.end ()) {if (Wordtimes2.find (word) = = WORDTIMES2.E         nd ()) wordtimes2[word] = 1;           else wordtimes2[word]++;                    if (Wordtimes2[word] <= Wordtimes[word]) cnt++;                        else {//the current word is in L, but it has appeared in the window the corresponding number of times, should not be added to the window//At this time, the window should be the starting position to move to the left, the first occurrence of the word position of the next word position for (int k = Winstart;; k + = Wordlen) {String TM                            Pstr = S.substr (k, Wordlen);                            wordtimes2[tmpstr]--;                                if (tmpstr = = Word) {Winstart = k + Wordlen;                            Break                        } cnt--; }} if (cnt = = L.size ()) Res.push_back (WI                Nstart);             } else {//Discover words not in l Winstart = winend + Wordlen;       Wordtimes2.clear ();                CNT = 0;    }}} return res; }};

There is also a code that did not debug successfully and subsequent modifications to ING.

Class Solution {public:vector<int> findsubstring (string s, vector<string>& words) {vector <        int> Res; int N = Words.size ();        Number of words if (N = = 0) return res;  int len = Words[0].length ();  Length of each word int strLen = s.length ();  Length of String map<string, int> countwords;                Get the WordCount map for (int i = 0; i < N; i + +) {if (Countwords.count (Words[i]))            countwords[words[i]]++;        else Countwords[words[i]] = 1;        } map<string, int> counting = countwords;        int begin = 0, tail = begin; while (tail < StrLen) {if (tail-begin + 1 = = N * len)//Get results {RE                S.push_back (begin);                Begin = tail + 1;                tail = begin;                counting = countwords;            Continue          }              string w = s.substr (tail, len);  int kind = Moveclass (w, counting);                Get the manner how to move the tail if (kind = = 1)//If w not in CountWords {                Begin = Tail + 2;                tail = begin;                counting = countwords;            Continue                } if (kind = = 2)//If w in countwords now {tail + = Len;            Continue if (kind = = 3)//If w in CountWords in past {string tmp = S.SUBSTR (begin, Tail-                Begin + 1);                Begin = Tmp.find (w) + 1;                tail = begin;                counting = countwords;            Continue     }} return res; } int Moveclass (string w, map<string, int>& counting) {if (Counting.count (w) = = 0) r        Eturn 1; else if (Counting[w] >= 1) {counting[w]--;           return 2;    } else return 3; }};









Substring with concatenation of all words--Problem Solving report (Window Move method)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.