[LeetCode] Add and Search Word

https://leetcode.com/problems/add-and-search-word-data-structure-design/#/description

Prefix Tree的构建和查找。

  • 插入单词的时候,挨个字符插入即可,记得最后做个标记(表示到这里是一个完整的单词)
  • 查找某个单词,由于有通配符.的存在,稍微麻烦一些。没碰到.时,按照前缀树的一般查找方法挨个往下查找即可,碰到.时,由于它可以代表其他任何一个字符,因此从前缀树当前节点往下的任何一个分支都需要搜索。
  • 查找可以用递归实现。
class TrieNode {
public:
    bool is_word;
    TrieNode* next[26];
    TrieNode() : is_word{false} {
        for (int i = 0; i < 26; ++i) {
            next[i] = NULL;
        }
    }
};

class WordDictionary {
public:
    /** Initialize your data structure here. */
    WordDictionary() {
        root = new TrieNode();
    }
    
    /** Adds a word into the data structure. */
    void addWord(string word) {
        if (word.empty()) return;
        TrieNode* p = root;
        for (char c : word) {
            if (!p->next[c-'a']) {
                p->next[c-'a'] = new TrieNode();
            }
            p = p->next[c-'a'];
        }
        p->is_word = true;
    }
    
    /** Returns if the word is in the data structure.
    A word could contain the dot character '.' to represent any one letter. */
    bool search(string word) {
        if (word.empty()) return true;
        return Search(word, 0, root);
    }

private:
    TrieNode* root;
    
    bool Search(string& word, int pos, TrieNode* p) {
        // 当前状态表示前缀word[0...pos-1]都已经匹配成功
        if (pos == word.length()) {
            if (!p) return false;
            else if (!p->is_word) return false;
            else return true;
        }
        
        if (word[pos] == '.') {
            for (int i = 0; i < 26; ++i) {
                if (p->next[i]) {
                    if ( Search(word, pos+1, p->next[i]) ) return true;
                }
            }
        } else {
            int idx = word[pos] - 'a';
            if (p->next[idx]) {
                return Search(word, pos+1, p->next[idx]);
            }
        }
        return false;
    }
};

前缀树的哈希表实现:

class TrieNode {
public:
    bool is_word;
    unordered_map<int, TrieNode*> next;
    TrieNode() : is_word{false} {}
};

class WordDictionary {
public:
    /** Initialize your data structure here. */
    WordDictionary() {
        root = new TrieNode();
    }
    
    /** Adds a word into the data structure. */
    void addWord(string word) {
        if (word.empty()) return;
        TrieNode* p = root;
        for (char c : word) {
            if (p->next.find(c-'a') == p->next.end()) {
                p->next[c-'a'] = new TrieNode();
            }
            p = p->next[c-'a'];
        }
        p->is_word = true;
    }
    
    /** Returns if the word is in the data structure.
    A word could contain the dot character '.' to represent any one letter. */
    bool search(string word) {
        if (word.empty()) return true;
        return Search(word, 0, root);
    }

private:
    TrieNode* root;
    
    bool Search(string& word, int pos, TrieNode* p) {
        if (pos == word.length()) {
            if (!p) return false;
            else if (!p->is_word) return false;
            else return true;
        }
        
        if (word[pos] == '.') {
            for (auto& kv : p->next) {
                if ( Search(word, pos+1, kv.second) ) return true;
            }
        } else {
            int idx = word[pos] - 'a';
            if (p->next.find(idx) != p->next.end()) {
                return Search(word, pos+1, p->next[idx]);
            }
        }
        return false;
    }
};

原文地址:https://www.cnblogs.com/ilovezyg/p/6933655.html