Tuesday, February 11, 2014

Substring with Concatenation of All Words

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:
1. Since there may be a word appear multiple times in words list, so use a Hash Map to record words frequency.
2. Check each indices to see if it satisfies the requirement. 

public class Solution {
    public ArrayList findSubstring(String S, String[] L) {
        int wordsNum = L.length;
        ArrayList ret = new ArrayList();
        if(wordsNum == 0) return ret;
        int wordLen = L[0].length();
        HashMap dict = new HashMap(); // one word may appear multiple times.
        for(String str : L){
            if(!dict.containsKey(str)){
                dict.put(str, 1);
            }
            else{
                dict.put(str, dict.get(str)+1);
            }
        }
        for(int i = 0; i <= S.length() - wordLen * wordsNum; i++){ // local optimization
            HashMap tmpDict = new HashMap();
            int j = 0;
            for(; j < wordsNum; j++){
                String str = S.substring(i + j * wordLen, i + j * wordLen + wordLen);
                if(!dict.containsKey(str))  break;
                if(!tmpDict.containsKey(str))
                    tmpDict.put(str, 1);
                else
                    tmpDict.put(str, tmpDict.get(str)+1);
                if(tmpDict.get(str) > dict.get(str)) break;
            }
            if(j == wordsNum) ret.add(i);
        }
        return ret;
        
    }
}

No comments:

Post a Comment