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.

Example 1:

Input:
s = "barfoothefoobarman",
words = ["foo","bar"]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.

Example 2:

Input:
s = "wordgoodstudentgoodword",
words = ["word","student"]
Output: []

Solution1:(TLE)

import itertools
class Solution:
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        if len(s)==0 or len(words)==0:
            return []
        res = set()
        for i in itertools.permutations(words):
            # print(i)
            begin = 0
            temp = ''.join(i)
            ans = s.find(temp)
            while ans!=-1:
                res.add(ans)
                begin += 1
                ans = s.find(temp,begin)
        return list(res)

Solution2:(still TLE)

import itertools
class Solution:
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        if len(s)==0 or len(words)==0:
            return []
        res = set()
        for i in itertools.permutations(words):
            temp = ''.join(i)
            for pos in range(len(s)-len(temp)+1):
                if s[pos:pos+len(temp)]==temp:
                    res.add(pos)
        return list(res)

Solution3:(TLE)

import copy
class Solution:
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        if len(s)==0 or len(words)==0:
            return []
        res = []
        length = len(words[0])
        totallength = length * len(words)
        for i in range(len(s)-totallength+1):
            temp = copy.deepcopy(words)
            pos = i
            flag = True
            # print(temp)
            while len(temp):
                if s[pos:pos+length] not in temp:
                    flag = False
                    break
                temp.remove(s[pos:pos+length])
                pos += length
            if flag:
                res.append(i)
        return res

just one case can't pass.
注意deepcopy的用法。
深拷贝是在复制的时候不但增加了一个指针,而且还给其分配了内存空间,即你原来有一个a列表,你这个a里的值都有指向自己的指针,而且也有自己的内存空间a1,当深拷贝a列表的时候得到一个A,这个A里的值都有指向自己的指针,而且也有自己的内存空间A1;那么你再对原来的进行操作的时候可以去a里去寻找,在A里进行操作,由于都有自己的独立的内存空间,那么不会相互影响。就可以避免遗漏值,出现错误。

Solution4:

class Solution:
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        if len(s)==0 or len(words)==0:
            return []
        res = []
        word = {}
        for i in words:
            if i not in word:
                word[i] = 1
            else:
                word[i] += 1
        length = len(words[0])
        totallength = length * len(words)
        for i in range(len(s)-totallength+1):
            dic = {}
            flag = True
            for j in range(i,i+totallength,length):
                if s[j:j+length] not in word:
                    flag = False
                    break
                if s[j:j+length] not in dic:
                    dic[s[j:j+length]] = 1
                else:
                    dic[s[j:j+length]] += 1
                    if dic[s[j:j+length]]>word[s[j:j+length]]:
                        flag = False
                        break
            if flag:
                res.append(i)
        return res