zoukankan      html  css  js  c++  java
  • 字典树及相关问题

    字典树模板题

    LeetCode 208. 实现Trie(前缀树)

    class Trie {
    public:
        /** Initialize your data structure here. */
        Trie() {
            isEnd = false;
            fill(begin(next), end(next), nullptr);
        }
        
        /** Inserts a word into the trie. */
        void insert(string word) {
            Trie* curr = this;
            for(auto ch : word){
                if(curr->next[ch-'a'] == nullptr){
                    curr->next[ch-'a'] = new Trie();
                }
                curr = curr->next[ch-'a'];
            }
            curr->isEnd = true;
        }
        
        /** Returns if the word is in the trie. */
        bool search(string word) {
            Trie* curr = this;
            for(auto ch : word){
                if(curr->next[ch-'a'] == nullptr){
                    return false;
                }
                curr = curr->next[ch-'a'];
            }
            return curr->isEnd;
        }
        
        /** Returns if there is any word in the trie that starts with the given prefix. */
        bool startsWith(string prefix) {
            Trie* curr = this;
            for(auto ch : prefix){
                if(curr->next[ch-'a'] == nullptr){
                    return false;
                }
                curr = curr->next[ch-'a'];
            }
            return true;
        }
    private:
        static const int R = 26;
        Trie* next[R];
        bool isEnd;
    };
    

    LeetCode 1032. 字符流
    反向建树

    class Trie {
    public:
        Trie(){
            isEnd = false;
            fill(begin(next), end(next), nullptr);
        }
            
        void insert(const string& word){
            Trie* curr = this;
            for(auto ch=word.rbegin();ch!=word.rend();++ch){
                if(curr->next[*ch-'a'] == nullptr){
                    curr->next[*ch-'a'] = new Trie();
                }
                curr = curr->next[*ch-'a'];
            }
            curr->isEnd = true;
        }
            
        bool query(const string& word){
            Trie* curr = this;
            for(auto ch=word.rbegin();ch!=word.rend();++ch){
                if(curr->next[*ch-'a'] != nullptr){
                    curr = curr->next[*ch-'a'];
                    if(curr->isEnd) return true;
                }else return false;
            }
            return false;
        }
    private:     
        static const int R = 26;
        Trie* next[R];
        bool isEnd;
    };
    
    class StreamChecker {
    public:
        StreamChecker(vector<string>& words) {
            trie = new Trie();
            for(auto& word : words){
                trie->insert(word);
            }
        }
        
        bool query(char letter) {
            buffer.push_back(letter);
            return trie->query(buffer);
        }
    private:
        Trie* trie;
        string buffer;
    };
    
    /**
     * Your StreamChecker object will be instantiated and called as such:
     * StreamChecker* obj = new StreamChecker(words);
     * bool param_1 = obj->query(letter);
     */
    

    字典树+DFS

    LeetCode 211. 添加与搜索单词

    class WordDictionary {
    public:
        /** Initialize your data structure here. */
        WordDictionary() {
            isEnd = false;
            fill(begin(next), end(next), nullptr);
        }
        
        /** Adds a word into the data structure. */
        void addWord(string word) {
            WordDictionary* curr = this;
            for(auto ch : word){
                if(curr->next[ch-'a'] == nullptr){
                    curr->next[ch-'a'] = new WordDictionary();
                }
                curr = curr->next[ch-'a'];
            }
            curr->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) {
            return search(word.begin(), word.end(), this);
        }
    private:
        bool isEnd;
        static const int R = 26;
        WordDictionary* next[R];
        
        template<typename ForwardIt>
        bool search(ForwardIt first, ForwardIt last, WordDictionary* root){
            if(first == last) return root->isEnd;
            if(*first == '.'){
                for(int i=0;i < R;++i){
                    if(root->next[i] != nullptr && search(first+1, last, root->next[i])) return true;
                }
            }else if(root->next[*first-'a'] != nullptr){
                return search(first+1, last, root->next[*first-'a']);
            }
            return false;
        }
    };
    
    /**
     * Your WordDictionary object will be instantiated and called as such:
     * WordDictionary* obj = new WordDictionary();
     * obj->addWord(word);
     * bool param_2 = obj->search(word);
     */
    

    LeetCode 677. 键值映射

    class MapSum {
    public:
        /** Initialize your data structure here. */
        MapSum() {
            val = 0;
            isEnd = false;
        }
        
        void insert(string key, int val) {
            MapSum* curr = this;
            
            for(auto ch : key){
                if(curr->next.count(ch) == 0){
                    curr->next.insert({ch, new MapSum()});
                }
                curr = curr->next[ch];
            }
            curr->val = val;
            curr->isEnd = true;
        }
        
        int sum(string prefix) {
            MapSum* curr = this;
            int ans = 0;
            for(auto ch : prefix){
                if(curr->next.count(ch) == 0){
                    return ans;
                }
                curr = curr->next[ch];
            }
            return dfs(curr);
        }
    private:
        unordered_map<char, MapSum*> next;
        int val;
        int isEnd;
        
        int dfs(MapSum* root){
            int sum = 0;
            for(auto it : root->next){
                if(it.second != nullptr){
                    sum += dfs(it.second);
                }
            }
            if(root->isEnd) sum += root->val;
            return sum;
        }
    };
    
    /**
     * Your MapSum object will be instantiated and called as such:
     * MapSum* obj = new MapSum();
     * obj->insert(key,val);
     * int param_2 = obj->sum(prefix);
     */
    

    LeetCode 820. 单词的压缩编码
    反向建树+DFS

    class Trie {
    public:
        Trie() {
            fill(begin(next), end(next), nullptr);
            isEnd = false;
        }
        
        void insert(string words) {
            Trie* curr = this;
            for(auto it = words.crbegin();it != words.crend(); ++it){
                if(curr->next[*it-'a'] == nullptr) {
                    curr->next[*it-'a'] = new Trie();
                }
                curr = curr->next[*it-'a'];
            }
            curr->isEnd = true;
        }
        
        int count(Trie* root, int cnt) {
            bool isLeaf = true;
            int sum = 0;
            for(int i = 0;i < R;++i) {
                if(root->next[i] != nullptr) {
                    isLeaf = false;
                    sum += count(root->next[i], cnt+1);
                }
            }
            return isLeaf ? cnt + 1 : sum;
        }
    private:
        static const int R = 26;
        Trie* next[R];
        bool isEnd;
    };
    
    class Solution {
    public:
        int minimumLengthEncoding(vector<string>& words) {
            Trie* trie = new Trie();
            for(const auto& it : words) {
                trie->insert(it);
            }
            int ans = trie->count(trie, 0);
            return ans ;
        }
    };
    
  • 相关阅读:
    python之进程和线程2
    Python学习笔记7:yield生成迭代器
    Python学习笔记6:装饰器
    Python学习你急5:文件打开与处理
    Python学习笔记4:集合方法
    Python学习笔记3:字典方法
    Python学习笔记2:列表操作方法详解
    Python学习笔记1:字符串方法
    番外篇:Vim使用方法
    Day12: 正则表达式
  • 原文地址:https://www.cnblogs.com/littleorange/p/12524567.html
Copyright © 2011-2022 走看看