Skip to main content

211.设计添加和搜索单词的数据结构

标签: trie, design, string

难度: Medium

通过率: 46.34%

原题链接: https://leetcode.com/problems/design-add-and-search-words-data-structure/description/

题目描述

设计一种支持添加新单词和查找是否有字符串匹配任何以前添加的字符串的数据结构。实现 WordDictionary 类:

  • WordDictionary() 初始化对象。
  • void addWord(word) 将单词添加到数据结构中,以后可以匹配。
  • bool search(word) 如果数据结构中存在与单词匹配的字符串,则返回 true,否则返回 false。单词可能包含点 '.',点可以匹配任何字母。

解题思路

为了高效实现这个问题,我们可以使用字典树(Trie)数据结构。字典树提供了一种高效的方式来存储大量字符串,并且支持高效的前缀查找和带有通配符的单词查找。这个题目的关键点在于需要支持任意位置的通配符 '.',这可以通过深度优先搜索的方式来处理。

解题步骤:

  1. 实现 Trie 节点的结构: 每个节点包含一个子节点数组(或者字典)指向它的孩子节点,以及一个布尔标志表示是否是一个完整的单词结尾。

  2. 建立 Trie 树: 实现 addWord 函数,将单词逐一添加到 Trie 树中。

  3. 搜索函数实现:search 函数实现递归的深度优先搜索。对于普通字符,沿着 Trie 树向下搜索;对于 '.',则递归遍历所有可能的子节点。

这种设计能够很好地处理最多含有两个 '.' 的搜索查询。递归地处理通配符部分,并进行回溯搜索,直到找到匹配的位置或确定没有匹配。

代码实现

class TrieNode:
def __init__(self):
self.children = {}
self.is_end_of_word = False

class WordDictionary:
def __init__(self):
self.root = TrieNode()

def addWord(self, word: str) -> None:
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end_of_word = True

def search(self, word: str) -> bool:
def dfs(index, node):
if index == len(word):
return node.is_end_of_word
char = word[index]
if char == '.':
return any(dfs(index + 1, child) for child in node.children.values())
if char in node.children:
return dfs(index + 1, node.children[char])
return False

return dfs(0, self.root)

复杂度分析

时间复杂度:

对于 addWord 操作,由于我们需要将该单词的每个字符插入到 Trie 中,所以时间复杂度是 O(L)O(L),其中 LL 是单词的长度。对于 search 操作,最坏情况下也需要遍历该单词的每个字符,因此时间复杂度是 O(L)O(L)。需要注意的是,search 在遇到通配符 '.' 时可能需要遍历多个字母的分支,但这一般不会影响复杂度。

空间复杂度:

在最坏的情况下,Trie 的空间复杂度是 O(N×L)O(N \times L),其中 NN 是插入单词的个数且 LL 是单词的平均长度,因为我们需要为 Trie 中的每个节点分配空间。