题目描述
给你一个 不含重复 单词的字符串数组 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
- 0 <= words[i].length <= 1000
- words[i] 仅由小写字母组成
- 0 <= sum(words[i].length) <= 105
题解思路
我们定义一个字典树 并将words中的单词按照长度从小到大排序 遍历
-
如果该单词未出现在字典树中 我们将其加入到字典树中
-
如果该单词出现在字典树中 且是组合词我们将其添加到ans中
如何判断是否该单词是否是一个组合词:
- 遍历该单词的每一个字符
- 如果遍历到某一个字符对应已有的单词结尾 则从下一个字符接着遍历
- 如果遍历到某一个字符对应的不存在字典树 则退出遍历
题解代码
class Trie:
def __init__(self):
self.children=[None]*26
self.isEnd=False
def insert(self,word):
node=self
for w in word:
w=ord(w)-ord('a')
if not node.children[w]:
node.children[w]=Trie()
node=node.children[w]
node.isEnd=True
def dfs(self,word,start):
if start==len(word):
return True
node=self
for i in range(start,len(word)):
node=node.children[ord(word[i])-ord('a')]
if node is None:
return False
if node.isEnd and self.dfs(word,i+1):
return True
return False
class Solution:
def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]:
ans=[]
words.sort(key=len)
root=Trie()
for word in words:
if word=='':
continue
if root.dfs(word,0):
ans.append(word)
else:
root.insert(word)
return ans