Given a string s and a non-empty string p, find all the start indices of P's anagrams in S.
Strings consists of lowercase 中文版 letters only and the length of both Strings s and P would not be larger than 20,100.
The order of output does not matter.
Example 1:
Input:s: "CBAEBABACD" P: "abc" output:[0, 6]explanation:the substring with start index = 0 is "CBA", which was an anagram of "ABC". The substring with start index = 6 are "BAC", which is an anagram of "ABC".
Example 2:
Input:s: "Abab" P: "AB" output:[0, 1, 2]explanation:the substring with start index = 0 is "AB", which are an anagram of "AB" . The substring with start index = 1 are "ba", which is an anagram of "AB". The substring with start index = 2 are "AB", which is an anagram of "AB".
This problem gives us two strings s and P, let us find the string p in the position of all variable positions, the so-called variable rank is the same number of characters but the order can be different two words, then we must first count the number of characters in the string p, and then from the beginning of S, Each time to find the P string length characters, to verify whether the number of characters is the same, if there is a direct break, if it has been the same, the starting position is added to the result res, see the code as follows:
Solution One:
classSolution { Public: Vector<int> Findanagrams (stringSstringp) {if(S.empty ())return {}; Vector<int> Res, CNT ( -,0); intNS = S.size (), NP = P.size (), i =0; for(CharC:P) + +Cnt[c]; while(I <NS) { BOOLSuccess =true; Vector<int> tmp =CNT; for(intj = i; J < i + NP; ++j) {if(--tmp[s[j]) <0) {Success=false; Break; } } if(Success) {res.push_back (i); } ++i; } returnRes; }};
We can write the above code more concise, with two hash tables, respectively, the number of characters p, and the number of characters in the first p string in S, and then compare, if the two are the same, then add 0 to the result res, and then begin to traverse the remaining characters in S, each time to the right to add a new character, Then remove an old character from the left, and compare the two hash tables again each time, see the code below:
Solution Two:
classSolution { Public: Vector<int> Findanagrams (stringSstringp) {if(S.empty ())return {}; Vector<int> Res, m1 ( the,0), M2 ( the,0); for(inti =0; I < p.size (); ++i) {++m1[s[i]]; ++M2[p[i]]; } if(m1 = = m2) res.push_back (0); for(inti = P.size (); I < s.size (); ++i) {++M1[s[i]]; --m1[s[i-p.size ()]; if(m1 = = m2) res.push_back (i-p.size () +1); } returnRes; }};
The following method of using sliding windows sliding window is also clever, first count the number of characters in the string p, and then use two variables left and right to represent a sliding window of the right and left boundary, with the variable CNT to indicate the number of characters in the string p to match, and then start the loop, If the right boundary character is already in the hash table, indicating that the character appears in P, then CNT self minus 1, then the hash table of the number of characters from 1, the right bound to add 1, if CNT is reduced to 0, the characters in P are matched, then the left boundary is added to the result Res. If the difference between right and left is the length of p, then the leftmost character should be removed, and we see if the character in the hash table is greater than or equal to 0, that character is the character in P, why, because above we have let each character subtract 1, if not the character in P, Then the number in the hash table should be 0, minus 1 is 1, so you know whether the character is P, if we remove a character belonging to P, CNT self-increment 1, see the code is as follows:
Solution Three:
classSolution { Public: Vector<int> Findanagrams (stringSstringp) {if(S.empty ())return {}; Vector<int> Res, M ( the,0); intleft =0, right =0, cnt = P.size (), n =s.size (); for(CharC:P) + +M[c]; while(Right <N) {if(m[s[right++]]-->=1) --CNT; if(CNT = =0) Res.push_back (left); if(Right-left = = P.size () && m[s[left++]]++ >=0) ++CNT; } returnRes; }};
Similar topics:
Valid Anagram
Anagrams
Resources:
Https://discuss.leetcode.com/topic/64390/c-o-n-solution/2
Https://discuss.leetcode.com/topic/64434/shortest-concise-java-o-n-sliding-window-solution
Leetcode all in one topic summary (continuous update ...)
[Leetcode] Find all anagrams in a string to find all the inflection words in a string