You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.
For example, given:
S: "barfoothefoobarman"
L: ["foo", "bar"]
You should return the indices: [0,9]
.
(order does not matter).
Solution:
create two HashMaps to store the words and the substrings (which contains the numbers of their occurence)
running time: O(nm), n is the length of the string, m is the size of the L[];
Note: watch the annotations.
是所有的单词的连接,不是每两个的连接,需要分清楚!
public class Solution { public ArrayList<Integer> findSubstring(String S, String[] L) { // Start typing your Java solution below // DO NOT write main() function ArrayList<Integer> result = new ArrayList<Integer>(); HashMap<String, Integer> sMap = new HashMap<String, Integer>(); HashMap<String, Integer> lMap = new HashMap<String, Integer>(); if(L==null){ return result; } int size = L.length; int len = L[0].length(); //set the HashMap for String[] L; for(int i=0; i<size; i++){ if(!lMap.containsKey(L[i])){ lMap.put(L[i], 1); }else{ int k = lMap.get(L[i]); lMap.put(L[i], k+1); } } for(int i=0; i<=S.length()-size*len; i++){ sMap.clear(); //this step is very important, //each time when i changes we need clear the relationship in HashMap sMap. int j=0; for(;j<size;j++){ String subS = S.substring(i+j*len, i+(j+1)*len); if(!lMap.containsKey(subS)){ break; } //set the HashMap for substring if(!sMap.containsKey(subS)){ sMap.put(subS,1); }else{ int k = sMap.get(subS); sMap.put(subS, k+1); } //if the occurence number of substring more than string in LMap if(sMap.get(subS) > lMap.get(subS)){ break; } } if(j == size){ result.add(i); } } return result; } }