目录

0472:连接词(★★)

力扣第 472 题

题目

给你一个 不含重复 单词的字符串数组 words ,请你找出并返回 words 中的所有 连接词

连接词 定义为:一个完全由给定数组中的至少两个较短单词(不一定是不同的两个单词)组成的字符串。

示例 1:

输入:words = ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]
输出:["catsdogcats","dogcatsdog","ratcatdogcat"]
解释:"catsdogcats" 由 "cats", "dog" 和 "cats" 组成;
"dogcatsdog" 由 "dog", "cats" 和 "dog" 组成;
"ratcatdogcat" 由 "rat", "cat", "dog" 和 "cat" 组成。

示例 2:

输入:words = ["cat","dog","catdog"]
输出:["catdog"]

提示:

  • 1 <= words.length <= 104
  • 1 <= words[i].length <= 30
  • words[i] 仅由小写英文字母组成。
  • words 中的所有字符串都是 唯一 的。
  • 1 <= sum(words[i].length) <= 105

分析

类似 0139,可以按第一个单词长度递归。

解答

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution:
    def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]:
        @cache
        def dfs(w):
            for i in range(1, len(w)):
                if w[:i] in vis and (w[i:] in vis or dfs(w[i:])):
                    return True
            return False
        vis = set(words)
        return [w for w in words if dfs(w)]

148 ms

*附加

同样的,可以用字典树来查找。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution:
    def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]:
        T = lambda: defaultdict(T)
        trie = T()
        res = []
        for w in sorted(words,key=len):
            @cache
            def dfs(i):
                if i==len(w):
                    return True
                p = trie
                for j in range(i,len(w)):
                    if w[j] not in p:
                        return False
                    p = p[w[j]]
                    if '#' in p and dfs(j+1):
                        return True
                return False
            if dfs(0):
                res.append(w)
            else:
                p = trie
                for c in w:
                    p = p[c]
                p['#'] = {}
        return res

540 ms