首页 > 技术文章 > lintcode-473-单词的添加与查找

libaoquan 2017-08-21 12:41 原文

473-单词的添加与查找

设计一个包含下面两个操作的数据结构:addWord(word), search(word)
addWord(word)会在数据结构中添加一个单词。而search(word)则支持普通的单词查询或是只包含.和a-z的简易正则表达式的查询。
一个 . 可以代表一个任何的字母。

注意事项

你可以假设所有的单词都只包含小写字母 a-z。

样例

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") // return false
search("bad") // return true
search(".ad") // return true
search("b..") // return true

标签

字典树

思路

使用字典树,如何实现一个字典树相关见 lintcode-442-实现 Trie

  • addWord 对应字典树的插入操作
  • search 对应字典树查询操作,不过需要注意 '.' (正则表达式)的操作,因为 '.' 可以对应任何字符,所以要遍历 '.' 对应节点的所有子树,而非像其他字符那样,遍历对应的一条子树就可以。且所有子树有一条符合既可以证明存在此单词,所以要将遍历结果执行 '或' 操作

code

/**
* Your Trie object will be instantiated and called as such:
* Trie trie;
* trie.insert("lintcode");
* trie.search("lint"); will return false
* trie.startsWith("lint"); will return true
*/
class TrieNode {
public:
    // Initialize your data structure here.
    char c;
    TrieNode * next[26];
    bool isEnd;

    TrieNode() {
        c = ' ';
        for (int i = 0; i < 26; i++) {
            next[i] = nullptr;
        }
        isEnd = false;
    }

    TrieNode(char c) {
        this->c = c;
        for (int i = 0; i < 26; i++) {
            next[i] = nullptr;
        }
        isEnd = false;
    }
};

class WordDictionary {
private:
    TrieNode* root;
    
public:
    WordDictionary() {
        root = new TrieNode();
    }
    
    // Adds a word into the data structure.
    void addWord(string word) {
        // Write your code here
        TrieNode* curNode = root;
        for (int i = 0; i < word.size(); i++) {
            if (curNode->next[word[i] - 'a'] != nullptr) {
                curNode = curNode->next[word[i] - 'a'];
            }
            else {
                TrieNode* node = new TrieNode(word[i]);
                curNode->next[word[i] - 'a'] = node;
                curNode = node;
            }
        }
        curNode->isEnd = 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) {
        // Write your code here
        return search(word, root);
    }

    bool search(string word, TrieNode* root) {
        if (word.size() == 0 && root != NULL) {
            return root->isEnd;
        }
        else if (word[0] != '.' && root != NULL) {
            return search(word.substr(1, word.size() - 1), root->next[word[0] - 'a']);
        }
        else if (word[0] == '.' && root != NULL) {
            bool result = false;
            for (int i = 0; i < 26; i++) {
                if (root->next[i] != nullptr) {
                    result = result | search(word.substr(1, word.size() - 1), root->next[i]);
                }
            }
            return result;
        }
        else if (root == NULL) {
            return false;
        }
    }
};

// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary;
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");

推荐阅读