LeetCode 30. Substring with Concatenation of All Words

来源:互联网 发布:youtube网络连接错误 编辑:程序博客网 时间:2024/05/17 23:45

题目:

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).

题意:

给定一个字符串s以及一个字符串链表words,找出在s中所有包含word所有字符的起始下标。


题解:

先写下自己做的思路(超时),

基本思路:

假设s='abcdefg'  words =['bc','de']

则以len(‘bc’)的长度为一次大循环, 

第一次循环时,依次查找以 ab cd ef 开头的字符串是否符合

第二次循环时,依次查找以bc de fg 开头的字符串是否符合


class Solution(object):    def findSubstring(self, s, words):        """        :type s: str        :type words: List[str]        :rtype: List[int]        """        res = []        s_len = len(s)        words_len = len(words)        str_len = len(words[0])                for i in range(str_len):              cur = i             words_del =[]   #被删除的字符串            while cur + len(words)*str_len <=len(s):                cur_word = s[cur:cur+str_len]                 if cur_word in words :   #在words中                    words_del.append(cur_word)                    flag = words.index(cur_word)                    del words[flag]                    if len(words) != 0:   #如果words不为空                        cur =cur+ str_len                    else:                        res.append(cur-(words_len-1)*str_len)                        cur = cur-(words_len-2)*str_len    #cur向前移(str_len)位                        words = words_del                        words_del =[]                elif cur_word not in words and len(words_del) != 0:   #如果存在开始匹对但后续又不在words中时                    cur = cur - (len(words_del)-1)*str_len                    words = words + words_del                    words_del =[]                else:   #一开始就不在words中                    cur = cur+str_len            i = i+1        return res


但是。。。 这样超时了。。


----------------------------分割线------------------------------------

参考后面讨论区想法,使用collection模块的Counter操作

对words中字符串出现的频率统计了,相应的增减。

具体如下:

from collections import Counterclass Solution(object):    def findSubstring(self, s, words):        result = []        word_len = len(words[0])        for stripe in range(word_len):  # each stripe starts at a different position in s, modulo word_len            i = stripe                  # the next index in s that we want to match a word            to_match = len(words)       # number of words still to be matched            freq = Counter(words)       # frequency of each words to be matched            while i + to_match*word_len <= len(s):  # remainder of s is long enough to hold remaining unmatched words                word = s[i:i+word_len]   # next part of s attempting to be matched                if word in freq:         # match, decrement freq count                    freq[word] -= 1                    if freq[word] == 0:                        del freq[word]                    to_match -= 1                    i += word_len                    if to_match == 0:               # all matched                        result.append(i - word_len*len(words))                elif to_match != len(words):        # some words have been matched                    nb_matches = len(words) - to_match                    first_word = s[i - nb_matches*word_len:i - (nb_matches-1)*word_len]                    freq.setdefault(first_word, 0)  # put first word matched back in dictionary                    freq[first_word] += 1                    to_match += 1                else:                               # no words matched                    i += word_len        return result


0 0