208. Implement Trie (Prefix Tree)(python+cpp)

题目:

Implement a trie with insert, search, and startsWith methods.
Example:

Trie trie = new Trie();
trie.insert("apple"); 
trie.search("apple");   // returns true
trie.search("app");     // returns false 
trie.startsWith("app"); //returns true 
trie.insert("app");    
trie.search("app");     // returns true 

Note:
You may assume that all inputs are consist of lowercase letters a-z.
All inputs are guaranteed to be non-empty strings.

解释:
实现字典树
python中用字典来表示子结点,用一个bool变量表示是否有一个单词到这个结点处结束,但是感觉这种写法并不是经典写法,而且也比较难以理解,更经典的写法应该是默认每个结点都有26个子节点(如果是英文单词的话),也可以把bool类型的is_word变成int类型的count,实现词频统计:

from collections import defaultdict
class TrieNode(object):
    def __init__(self):
        self.children=defaultdict(TrieNode)
        self.is_word=False
class Trie(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.root=TrieNode()

    def insert(self, word):
        """
        Inserts a word into the trie.
        :type word: str
        :rtype: void
        """
        current=self.root
        for letter in word:
            current=current.children[letter]
        #在最后一个字母的位置,is_word变为True
        current.is_word=True          

    def search(self, word):
        """
        Returns if the word is in the trie.
        :type word: str
        :rtype: bool
        """
        current=self.root
        for letter in word:
            current=current.children.get(letter)
            #如果不存在这个键
            if current==None:
                return False
        #如果不是一个完整的单词,那么也是返回False,比如,树中存在"abc"但是word="ab"的情况
        return current.is_word

    def startsWith(self, prefix):
        """
        Returns if there is any word in the trie that starts with the given prefix.
        :type prefix: str
        :rtype: bool
        """
        current=self.root
        for letter in prefix:
            current=current.children.get(letter)
            if current==None:
                return False
        return True

# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)

啊,终于自己摸索着写出c++代码了:

#include<map>
using namespace std;
struct TrieNode {
    bool isWord;
    char c;
    map<char,TrieNode*> children;
    TrieNode(char x) : c(x),isWord(false){}
    TrieNode() : isWord(false){}
};
class Trie {
public:
    /** Initialize your data structure here. */
    TrieNode* root;
    Trie() {
        
        root=new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        TrieNode* current=root;
        for(auto letter:word)
        {
            if (!current->children.count(letter))
                current->children[letter]=new TrieNode(letter);
            current=current->children[letter];
        }
        current->isWord=true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        TrieNode * current=root;
        for(int i=0;i<word.size();i++ )
        {
            char letter=word[i];
            if (!current->children.count(letter))
                return false;           
            current=current->children[letter];
        }
        return current->isWord;  
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        TrieNode * current=root;
        for(auto letter:prefix)
        {
            if (!current->children.count(letter))
                return false;
            current=current->children[letter];
        }
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * bool param_2 = obj.search(word);
 * bool param_3 = obj.startsWith(prefix);
 */

注意新建结点之前一定要判断这个子节点是否存在,如果存在就不新建了,盲目新建会导致把以前的路径删除,使得答案不对。
总结:
字典树相关的知识:

Trie树(Prefix Tree)介绍
6天通吃树结构—— 第五天 Trie树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值