[211]. 添加与搜索单词 - 数据结构设计

Posted Debroon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[211]. 添加与搜索单词 - 数据结构设计相关的知识,希望对你有一定的参考价值。

添加与搜索单词 - 数据结构设计

 


题目

题目:https://leetcode-cn.com/problems/design-add-and-search-words-data-structure/

 


函数原型

class WordDictionary 
public:
    WordDictionary() 
    void addWord(string word) 
    bool search(string word) 
;

 


字典树支持通配符查询


字符串的存储,可用 Trie 实现,唯一不同的地方在于:

  • WordDictionary 类查找到 . 时 ,支持任意匹配。

任意匹配在 Trie 中如下所示:


都可以匹配,意味着我们需要做一次搜索,必须遍历所有的可能。

因为这是一颗树,遍历的方式应该采用递归,方便实现。

class Trie
    vector<Trie*> next;                                // 指针数组,数组中存放的是指针,默认为 nullptr
    bool isEnd;
    
public:
    Trie() : next(26, nullptr), isEnd(false) 

	/* 向 Trie 中添加一个新的单词 */
    void insert(string s) 
        Trie *root = this;                             // 声明一个变量,初始的时候在 root 位置
        for(auto &c : s)                              // 每次取出一个字符
            int x = c - 'a';                           // 一个单词可能另一个单词的前缀,避免重复创建
            if(root->next[x] == nullptr)               // 检查节点的孩子节点是否存在字母 c 这个结点
                root->next[x] = new Trie();            // 不重复,才创建
            root = root->next[x];                      // 如果已经存在,就直接走到孩子结点
        
        root->isEnd = true;                            // 直到 root 来到最后一个字符,表示添加完毕
    

    bool search(string s) return dfs(s, 0, this);    // 从根开始搜索

    bool dfs(string s, int k, Trie *root) 
        if( k == s.size() )                            // 整个单词已经考虑完了
            return root->isEnd;                         

        char c = s[k];                                 // 保存当前字符,字符有俩种情况:字母和点
        if(c != '.')                                  /* 字母 */
            int x = c - 'a';
            if( root->next[x] == nullptr )             // 当前节点是否有 c 这个节点
                return false;                          // 没有的话,匹配失败
            return dfs(s, k + 1, root->next[x]);       // 有的话,继续下一个字符匹配
         else                                        /* 点 */
            for(int j = 0; j < 26; j++)                // 支持任意字符匹配
                if(root->next[j] && dfs(s, k + 1, root->next[j]))
                    return true;                       // 思想同,不过通过 && 连起来写了
        
        return false;                                  // 都匹配失败
     
;

class WordDictionary 
    Trie *trie;                                        // 底层实现是 字典树
public:
    WordDictionary()  trie = new Trie(); 
    void addWord(string word)  trie->insert(word);   
    bool search(string word)  return trie->search(word); 
;

以上是关于[211]. 添加与搜索单词 - 数据结构设计的主要内容,如果未能解决你的问题,请参考以下文章

[211]. 添加与搜索单词 - 数据结构设计

leetcode-211-添加与搜索单词-数据结构设计

LeetCode 211.添加与搜索单词

leetcode 211. 添加与搜索单词 - 数据结构设计 解题报告

LeetCode 211.添加与搜索单词, swift

211. 添加与搜索单词 - 数据结构设计trie数的基本操作