實現 Trie

題目:

實現一個 Trie,包含 insert, search, 和 startsWith 這三個方法。spa

樣例:

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

什麼是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;
    }
};
相關文章
相關標籤/搜索