当前位置: 面试刷题>> 添加与搜索单词 - 数据结构设计(经典算法150题)


### 题目描述 设计一个数据结构,支持添加字符串和搜索字符串中的前缀或任意子串的功能。具体地说,你需要实现以下功能: 1. **`addWord(word)`**:向数据结构中添加一个单词。 2. **`search(word)`**:返回单词是否可以在数据结构中的某个单词里找到。单词中的字母顺序可以被打乱。 3. **`startsWith(prefix)`**:返回是否有任何单词以给定的前缀开始。 ### 示例 假设我们有以下操作: ``` Trie trie = new Trie(); trie.addWord("hello"); trie.addWord("world"); trie.search("world"); // 返回 true trie.search("word"); // 返回 false trie.startsWith("wor"); // 返回 true trie.startsWith("wo"); // 返回 false trie.search("hell"); // 返回 false trie.search(""); // 返回 false(空字符串不被视为单词) ``` ### 解题思路 为了实现这个功能,我们可以使用**Trie(前缀树)**结合**集合(Set)**来存储每个单词的字符的所有排列。具体来说,对于每个添加到Trie中的单词,我们可以生成其所有字符的排列,并将这些排列存储在Trie节点对应的集合中。然而,这种方法的空间复杂度会非常高。 为了优化空间复杂度,我们可以采用一个更巧妙的方法:在Trie的每个节点上,除了存储子节点指针外,还存储一个布尔数组或位集合(bitset),用于表示当前节点下是否可以形成某个特定长度的单词(不考虑顺序)。对于`startsWith`操作,我们只需遍历Trie直到前缀的最后一个字符即可。对于`search`操作,我们需要在Trie中找到一个路径,使得路径上的节点能够构成给定单词的所有字符(不考虑顺序),这通常涉及到更复杂的逻辑或额外的数据结构。 但为简化实现,以下示例代码将只展示使用Trie结构实现`addWord`和`startsWith`功能,并假设`search`操作需要额外的数据结构或逻辑来支持乱序搜索(这里不展开)。 ### PHP 示例代码 ```php class TrieNode { public $children = []; public $isEndOfWord = false; public $startsWithPrefix = false; public function __construct() { $this->children = array_fill(0, 26, null); } } class Trie { private $root; function __construct() { $this->root = new TrieNode(); } function addWord($word) { $node = $this->root; $node->startsWithPrefix = true; // Mark root as starting point for ($i = 0; $i < strlen($word); $i++) { $index = ord($word[$i]) - ord('a'); if (!isset($node->children[$index])) { $node->children[$index] = new TrieNode(); } $node = $node->children[$index]; $node->startsWithPrefix = true; // Mark each node in path as part of some prefix if ($i == strlen($word) - 1) { $node->isEndOfWord = true; } } } function startsWith($prefix) { $node = $this->root; for ($i = 0; $i < strlen($prefix); $i++) { $index = ord($prefix[$i]) - ord('a'); if (!isset($node->children[$index]) || !$node->children[$index]->startsWithPrefix) { return false; } $node = $node->children[$index]; } return true; } } ``` 请注意,上述PHP代码实现了`addWord`和`startsWith`功能,但没有实现完整的`search`功能以支持乱序搜索。对于`search`功能的完整实现,您可能需要引入额外的数据结构或逻辑来处理字符的乱序问题。 类似地,Python和JavaScript的实现逻辑会非常相似,只是语法和库的使用上会有所不同。
推荐面试题