返回

串联所有单词的子串 | 算法(leetode,附思维导图 + 全部解法)300题

前端




一、题目

给定一个字符串s和一个单词列表wordDict,找到所有能串联所有给定单词的子字符串。

示例:

输入:s = "barfoothefoobarman", wordDict = ["foo","bar"]
输出:["barfoot","barfoo"]

解释:

"barfoot"是由"bar""foot"串联而成
"barfoo"是由"bar""foo"串联而成

二、解法总览(思维导图)

思维导图

三、全部解法

1 方案1

这是一种暴力破解法,时间复杂度为O(n^2)。

1)代码:

def findSubstrings(s, wordDict):
    result = []
    for i in range(len(s)):
        for j in range(i + 1, len(s) + 1):
            substring = s[i:j]
            if substring in wordDict:
                result.append(substring)
    return result

2 方案2

这是一种使用哈希表的方法,时间复杂度为O(n)。

1)代码:

def findSubstrings(s, wordDict):
    wordDict = set(wordDict)
    result = []
    for i in range(len(s)):
        substring = ""
        for j in range(i, len(s)):
            substring += s[j]
            if substring in wordDict:
                result.append(substring)
            else:
                break
    return result

3 方案3

这种解法利用了滚动哈希,使算法的时间复杂度降低到O(n)。

1)代码:

def findSubstrings(s, wordDict):
    wordDict = set(wordDict)
    result = []
    windowStart = 0
    windowEnd = 0
    wordCount = {}
    for word in wordDict:
        wordCount[word] = 0
    targetCount = len(wordDict)
    matchedCount = 0
    while windowEnd < len(s):
        rightChar = s[windowEnd]
        if rightChar in wordCount:
            wordCount[rightChar] += 1
            if wordCount[rightChar] == 1:
                matchedCount += 1
        windowEnd += 1
        while matchedCount == targetCount:
            leftChar = s[windowStart]
            if leftChar in wordCount:
                wordCount[leftChar] -= 1
                if wordCount[leftChar] == 0:
                    matchedCount -= 1
            result.append(s[windowStart:windowEnd])
            windowStart += 1
    return result