Substring with Concatenation of All Words

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly 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).

Solution

from collections import defaultdict

class Solution(object):
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        result, n_word, l_word  = [], len(words), len(words[0])
        word_map = defaultdict(int)

        for i in words:
            word_map[i] += 1

        for i in range((len(s) + 1) - n_word * l_word):
            cur, j, = defaultdict(int), 0
            while j < n_word:
                word = s[i + j * l_word: i + j * l_word + l_word]
                if word not in word_map:
                    break
                cur[word] += 1
                if cur[word] > word_map[word]:
                    break
                j += 1
            if j == n_word:
                result.append(i)
        return result
public class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new ArrayList<>();

        if(s == null || words == null || words.length == 0) return res;
        int len = words[0].length();

        Map<String, Integer> map = new HashMap<>();
        for(String word : words)
            map.put(word, map.containsKey(word) ? map.get(word) + 1 : 1);

        for(int i = 0;i <= s.length() - len * words.length;i++) {
            Map<String, Integer> copy = new HashMap<>(map);

            for(int j = 0;j<words.length;j++) {
                String cur = s.substring(i + j * len, i + j* len + len);

                if(copy.containsKey(cur)) {
                    int count = copy.get(cur);

                    if(count == 1) copy.remove(cur);
                    else copy.put(cur, count - 1);

                    if(copy.isEmpty()) {
                        res.add(i);
                        break;
                    }
                } else break;
            }
        }

        return res;
    }
}

results matching ""

    No results matching ""