Title:
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).
Test Instructions:
Given a string s, and a set of string array words, all string lengths in the array are the same. Find the starting label of all substrings from the string s , which is a combination of all the strings in the words , and each string appears only once and no other characters are inserted between them, the order of the strings does not matter.
Algorithm Analysis:method One:
* Because the length of all words in L is the same, so according to Wordlen, can be divided into Wordlen group, the actual meaning is such.
* In the title Barfoothefoobarman example, l medium Word length is 3, can be divided into
* Bar|foo|the|foo|bar|man
* Ba|rfo|oth|efo|oba|rma|n
* B|arf|oot|hef|oob|arm|an
* In this way, for each grouping, you can use the idea of the minimum sliding window to quickly determine if the required string is included.
* Visually, it is necessary to start the search from each character, in fact, the use of two pointers to find the strings in s to meet the conditions, and each +wordlen, and will not repeat the system *, saving
* A lot of time.
Method Two:
The idea is still to maintain a window, and if the current word is in the dictionary, move on to the right end of the window, otherwise the left side of the window can jump to the next word in the string. Suppose the source string is n in length, and the word length in the dictionary is L. Because it is not a character, we need to judge all substrings of the source string that are of length L. Each time the string is truncated in the source string and the length of all strings in the dictionary is equal, judging whether the new truncated substring matches the strings in the dictionary, the match is added to the result, and the mismatch continues to intercept the new substring in the source string, repeating the process until the end.
AC Code:method One:
<span style= "FONT-SIZE:12PX;" >public class solution{public arraylist<integer> findsubstring (String S, string[] L) {ARRAYLIST&L t;integer> list = new arraylist<integer> (), int len = l.length;if (len = = 0) return list;int Wordlen = l[0].length (); map<string, integer> wordsmap = new hashmap<string, integer> (); for (int i = 0; i < len; i++) {int num = 1;i F (Wordsmap.get (l[i]) = null) num + = Wordsmap.get (L[i]); Wordsmap.put (l[i], num);} int slen = s.length (); int max = Slen-wordlen + 1;for (int i = 0; i < Wordlen; i++) {map<string, integer> Nummap = new hashmap<string, integer> (); int count = 0;int start = i;for (int end = start; end < Max; end + = Wordlen) {St Ring TempStr = s.substring (end, end + Wordlen); if (!wordsmap.containskey (TEMPSTR))//The given string array does not contain the current string and jumps directly to the next string { Nummap.clear (); count = 0;start = end + wordlen;continue;} int num = 1;if (Nummap.containskey (TEMPSTR)) num + = Nummap.get (TEMPSTR); Nummap.put (TEMPSTR, num); if (NuM <= Wordsmap.get (TEMPSTR)) count++;//self-add else {while (Nummap.get (TEMPSTR) > Wordsmap.get) only if it is less than the given array element number ( TEMPSTR) {TempStr = s.substring (start, start + Wordlen);//When the number of elements in the current map trailer is greater than the given array element, the map header element nummap.put is removed (TEMPSTR, Nummap.get (TEMPSTR)-1); if (Nummap.get (TEMPSTR) < Wordsmap.get (TEMPSTR)) count--;//removed the element, the number is missing a start + = The wordlen;//corresponding starting element also moves back a}}if (count = = len) {list.add (start); tempstr = s.substring (start, start + Wordlen);// When the condition is met, the first element is removed, that is, to move back one position, to see if the following conditions are not nummap.put (TempStr, Nummap.get (TEMPSTR)-1); Count--;start + = Wordlen;} }}return list; }}</span>
Method Two:
public class Solution {public list<integer> findsubstring (String S, string[] L) {list<integer> Result=new arraylist<integer> (); if (l.length==0| | S.length () ==0) return result; int Wordlen=l[0].length (); Map storing L hashmap<string,integer> map=new hashmap<string,integer> (); for (int i=0;i<l.length;i++) {Integer value=map.get (l[i]); if (value==null) value=1; else value+=1; Map.put (L[i],value); } for (int i=0;i+wordlen<=s.length (); i++) {if (i + Wordlen * l.length > S.length ()) {break; } if (Map.containskey (s.substring (I,i+wordlen))) {Boolean b=checkstring (s.substring (i , I+wordlen*l.length), new hashmap<string,integer> (map), Wordlen); if (b==true) result.add (i); } } return result; }//Check string s is not a combination of strings in map public boolean checkstring (string s,hashmap<string,integer> map,int Wordlen) { Boolean flag=true; int i=0; while (S.length () >0) {String temp=s.substring (0,wordlen); Integer Value=map.get (temp); if (value==null| | value==0) {flag=false; Break }else{value-=1; Map.put (Temp,value); S=s.substring (Wordlen);//The substring starts at the character at the specified index until the end of the string. }} return flag; }}
Copyright NOTICE: This article is the original article of Bo Master, reprint annotated source
[Leetcode] [Java] Substring with concatenation of all Words