题目:

实现一个 Trie,包含 insert, search, 和 startsWith 这三个方法。

样例:

insert("lintcode")
search("code") // return false
startsWith("lint") // return true
startsWith("linterror") // return false
insert("linterror")
search("lintcode) // return true
startsWith("linterror") // return true

什么是Tire:

  • Trie,又称前缀树,字典树或者单词查找树。可以保存一些字符串->值的对应关系。基本上,它跟 Java 的 HashMap 功能相同,都是 key-value 映射,只不过 Trie 的 key 只能是字符串。它是一种用于快速检索的多叉数结构。例如,英文字母的字典树是26叉数,数字的字典树是10叉树。
  • Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
  • 如给出字符串"abc","ab","bd","dda",根据该字符串序列构建一棵Trie树。则构建的树如下:
    clipboard.png
  • Trie树的基本性质可以归纳为:
    (1)根节点不包含字符,除根节点意外每个节点只包含一个字符。
    (2)从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
    (3)每个节点的所有子节点包含的字符串不相同。
    (4)每个单词的公共前缀作为一个字符节点保存。
    (5)如果字符的种数为n,则每个结点的出度为n,这也是空间换时间的体现,浪费了很多的空间。
    (6)插入查找的复杂度为O(n),n为字符串长度。
思路:
树节点采用哈希表来映射字母和子节点的关系。

参考答案:

//定义树节点
class TrieNode{
  public:
  unordered_map<char, TrieNode*> ChildNode;
  bool isLeaf;
  TrieNode(){
      isLeaf = false;//确定一个字符串是否结束
  }
};

class Trie {
public:
    TrieNode * root;
    Trie() {
        // do intialization if necessary
        root = new TrieNode();
    }

    /*
     * @param word: a word
     * @return: nothing
     */
    void insert(string &word) {
        // write your code here
        TrieNode *cur = root;
        for(int i=0; i<word.size(); i++){
            if(cur->ChildNode.find(word[i]) == cur->ChildNode.end()){
                cur->ChildNode[word[i]] = new TrieNode();
            }
            cur = cur->ChildNode[word[i]];
        }
        cur->isLeaf = true;
    }

    /*
     * @param word: A string
     * @return: if the word is in the trie.
     */
    bool search(string &word) {
        // write your code here
        TrieNode *cur = root;
        for(int i=0; i<word.size(); i++){
            if(cur->ChildNode.find(word[i]) == cur->ChildNode.end()){
                return false;
            }
            cur = cur->ChildNode[word[i]];
        }
        if(cur->isLeaf)  return true;
        else    return false;
    }

    /*
     * @param prefix: A string
     * @return: if there is any word in the trie that starts with the given prefix.
     */
    bool startsWith(string &prefix) {
        // write your code here
        TrieNode *cur = root;
        for(int i=0; i<prefix.size(); i++){
            if(cur->ChildNode.find(prefix[i]) == cur->ChildNode.end()){
                return false;
            }
            cur = cur->ChildNode[prefix[i]];
        }
        return true;
    }
};

wydong
40 声望5 粉丝

wyd


« 上一篇
超级丑数