[前缀树]leetcode667:键值映射(medium)

题目:
在这里插入图片描述
题解1:
本题采用前缀树来解题,前缀树节点设有三个成员变量,sumval用来存储字符串前缀的val(前缀就是除去尾字符之前的字符叫前缀)以及相同的key要更新前缀的val,字符串尾字符的val就是记录字符串的val,next[26]表示每个节点值可以取到26个小写字母中的一个。这里我们用一个haspmap来记录遇到相同的key时,原来的val将被替代。

代码如下:

class MapSum {
public:
    struct TrieTree{
        int val,sumval;
        TrieTree *next[26]{nullptr};//下一个节点值
        TrieTree():val(0),sumval(0){};
    };
private:
    TrieTree *root;//前缀树根节点
    unordered_map<string,int> record; 
public:
    /** Initialize your data structure here. */
    MapSum() {
        root=new TrieTree();
        record.clear();
    }
    
    void insert(string key, int val) {
        TrieTree* note=root;
        int size=key.size();
        for(int i=0;i<size;++i)
        {
            int pos=key[i]-'a';
            if(note->next[pos]==nullptr)note->next[pos]=new TrieTree();//节点值不存在,就添加一个新节点
            if(i!=size-1)(note->next[pos])->sumval+=val-record[key];//用sumval来记录字符串前缀的val值或相同key需要更新sumval记录的前缀值
            note=note->next[pos];
        }
        record[key]=val;//更新关键字的val
        note->val=val;//字符串的val
    }
    
    int sum(string prefix) {
        TrieTree* note=root;
        for(auto p:prefix)
        {
            if(note->next[p-'a']==nullptr)return 0;//字符p不是前缀树的某个前缀,直接返回0
            note=note->next[p-'a'];
        }
        return note->val+note->sumval;//其他字符串的前缀和+该字符串的val
    }
};

题解2:使用map来代替前缀树节点,利用map的自排序功能,遍历record来查找前缀,累加和为reuslt

class MapSum{
private:
    map<string,int> record;
public:
    MapSum() {
        
    }
    
    void insert(string key, int val) {
        record[key]=val;
    }
    
    int sum(string prefix) {
        int result=0;
        for(auto iter:record)
        {
            string str=iter.first;
            if(str.find(prefix)==0)//prefix是str的前缀
                result+=iter.second;
        }
        return result;
    }
    
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值