leetcode6183

字符串的前缀分数和

刚开始一直在用哈希,结果超时了,然后再开了一个哈希表优化了一下,没想到还是超时。左思右想想不到其它方法,看了题解才知道可以用字典树。前缀+字符串,这不是妥妥的字典树吗,看来是字典树的知识都快忘完了。

思路:构建一棵前缀树,开一个26大小的结构体数组来存储,每经过一个节点就在该节点的位置加1,表示以该节点结尾的前缀单词的数量。

class Solution {
    struct Trie{
        int val;
        Trie* trie[26];
        Trie(){
            val = 0;
            for(int i = 0; i < 26; i++)
                trie[i] = nullptr;
        }
    };
public:
    vector<int> sumPrefixScores(vector<string>& words) {    
        vector<Trie*> t(26);

        for(string word: words){
            if(t[word[0] - 'a'] == nullptr)
                t[word[0] - 'a'] = new Trie();
            auto now = t[word[0]-'a'];
            for(int i = 1; i < word.size(); i++){
                now->val++;
                if(now->trie[word[i]-'a'] == nullptr)
                    now->trie[word[i]-'a'] = new Trie();
                now = now->trie[word[i]-'a'];
            }
            now->val++;
        }

        vector<int> res;
        for(string word : words){
            auto now = t[word[0]-'a'];
            int sum = 0;
            for(int i = 1; i < word.size(); i++){
                sum +=now->val;
                now = now->trie[word[i]-'a'];
            }
            sum += now->val;
            res.push_back(sum);
        }
        return res;
    }
};

趁热打铁

单词替换

题意:将一个句子中的所有单词替换为该单词的词根。

思路:根据所有的词根构建一棵前缀树,然后拿到句子的每个单词去遍历,如果遍历到的节点是词根的节点,那么用这个词根替换原句子中的单词。

class Solution {
    struct Trie{
        bool is_end;  //该节点是否为词根的结尾
        Trie* trie[26];
        Trie(){
            is_end = false;
            for(int i = 0; i < 26; i++)
                trie[i] = nullptr;
        }
    };
    Trie* root = new Trie();   
public:
   
    void buildTree(vector<string>& dictionary){
        
        for(string s: dictionary){
            Trie* node = root;
            for(char c: s){
                if(!node->trie[c-'a'])
                    node->trie[c-'a'] = new Trie();
                node = node->trie[c-'a'];
            }
            node->is_end = true;
        }
    }
    
    string search(string str){
        Trie* node = root;
        int index = 0;
        for(char c : str){
            //找最短的词根
            if(!node->trie[c-'a'] && !node->is_end) return str;
            if(node->is_end ) return str.substr(0, index);
            node = node->trie[c-'a'];
            index++;
        }
        
        return str.substr(0, index);
    }

    string replaceWords(vector<string>& dictionary, string sentence) {

        buildTree(dictionary);
        string res = "";
        string str = "";
        for(int i = 0; i < sentence.size(); i++){
            if(sentence[i] == ' ' ){
                res += search(str) + ' ';   
                str = "";
            }else{
                str +=sentence[i];
            }
        }
        res += search(str);  
        return res;
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值