Wednesday, January 7, 2015

LeetCode 30: 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).
public class Solution {
    public List<Integer> findSubstring(String S, String[] L) {
        List<Integer> list = new LinkedList<>();
        int n = L.length;
        
        if (n == 0)
            return list;
        
        int lenS = S.length();   
        int lenL = L[0].length();
        
        if (lenS==0 || lenL==0 || lenS<lenL*n)
            return list;
        
        // Use HashMap to store 'L': String and appearsing times in L.
        // Note: L may have some duplicates, we can't use HashSet just to store 'String' value. 
        Map<String, Integer> map = new HashMap<>();
        
        for (String str : L)
        {
            if (!map.containsKey(str))
                map.put(str, 1);
            else
                map.put(str, map.get(str)+1);
        }
        
        for (int i = 0; i < lenS-lenL*n+1; i++)
        {
            Map<String, Integer> copyMap = new HashMap<>(map);
            
            int j = i;
            
            // Search range from i to i+lenL*n-1
            while (j <= i+lenL*(n-1))
            {
                String searched = S.substring(j, j+lenL);
                
                if (copyMap.containsKey(searched))
                {
                    if (copyMap.get(searched) == 1)
                        copyMap.remove(searched);
                    else
                        copyMap.put(searched, copyMap.get(searched)-1);
                }   
                else
                    break;
                    
                j += lenL;
            }
            
            if (copyMap.isEmpty())
                list.add(i);
        }
        
        return list;
    }
}

No comments:

Post a Comment