Tuesday, January 14, 2014

Substring with Concatenation of All Words (Java)

Brute Force Solution, looking forward to better one
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).
Time complexity: O((M - N) * N)
public class Solution {
public ArrayList<Integer> findSubstring(String S, String[] L) {
ArrayList<Integer> result=new ArrayList<Integer> ();
if (S==null||L==null||S.length()==0 ||L.length==0){
return result;
}
int wordLen=L[0].length();
int totalLen=wordLen*L.length;
if (S.length()<totalLen){
return result;
}
HashMap<String, Integer> checker=new HashMap<String, Integer>();
for (String temp: L){
if (checker.containsKey(temp)){
checker.put(temp, checker.get(temp)+1);
}
else{
checker.put(temp,1);
}
}
for(int i=0; i<=S.length()-totalLen; i++){
if (isValid(checker, S, i,wordLen, totalLen)){
result.add(i);
}
}
return result;
}
private boolean isValid(HashMap<String, Integer> checker,String S, int i, int wordLen, int totalLen){
HashMap<String, Integer> tmpChecker=new HashMap<String, Integer>(checker);
int start=i;
int end=i+wordLen;
while(end-i<=totalLen){
String tmpString=S.substring(start, end);
if (tmpChecker.containsKey(tmpString)){
if (tmpChecker.get(tmpString)==0){
return false;
}
tmpChecker.put(tmpString, tmpChecker.get(tmpString)-1);
start=end;
end=start+wordLen;
}
else{
return false;
}
}
return true;
}
}

No comments:

Post a Comment