leetcode-每日一题2021.11.14 键值映射

leetcode 专栏收录该内容
111 篇文章 0 订阅

题目

力扣

思路一 暴力查找

使用哈希表存储每一个键值对,计算sum时就在哈希表里一个个找前缀符合的键,再获取值。

代码一

class MapSum {
public:
    MapSum() {

    }
    
    void insert(string key, int val) {
        mp[key]=val;
    }
    
    int sum(string prefix) {
        int sum=0;
        for(auto it=mp.begin();it!=mp.end();it++){
            if((it->first).substr(0,prefix.size())==prefix)
                sum+=it->second;
        }
        return sum;
    }
private:
    unordered_map<string,int> mp;
};

思路二 哈希表存储前缀

使用两个哈希表,一个哈希表存储键值对,一个哈希表存储前缀和以这个字符串为前缀的val和。sum函数可以直接返回第二个哈希表。每插入一个键值对,对其每一个前缀,更新值。更新的值有两种情况,第一种是如果这个key之前不存在,就直接加上现在的val,第二种是如果这个key之前存在,那么加上的需要是delta=val-原来的val。

代码二

class MapSum {
public:
    MapSum() {

    }
    
    void insert(string key, int val) {
        int delta=val;
        if(map.count(key))
            delta-=map[key];
        map[key]=val;
        for(int i=1;i<=key.size();i++){
            prefixmap[key.substr(0,i)]+=delta;
        }
    }
    
    int sum(string prefix) {
        return prefixmap[prefix];
    }
private:
    unordered_map<string,int> map;
    unordered_map<string,int> prefixmap;
};

思路三 Trie前缀树

定义一个前缀树的结构体,直接在前缀对应的 Trie 的每个节点存储该前缀对应的值。哈希表用来更新key对应的val,还有计算delta。每插入一个数,就顺着字符顺序一个个存下来,并给经过的每一个结点加上delta,如果不存在这个结点,就new一个结点。sum函数,循环,找到prefix对应的结点,并且返回val,如果prefix结点不存在就返回0.

代码三

struct TrieNode{
    int val;
    TrieNode *next[26];
    TrieNode(){
        this->val=0;
        for(int i=0;i<26;i++){
            this->next[i]=nullptr;
        }
    }
};
class MapSum {
public:
    MapSum() {
        this->root=new TrieNode();
    }
    
    void insert(string key, int val) {
        int delta=val;
        if(cnt.count(key)){
            delta-=cnt[key];
        }
        cnt[key]=val;
        TrieNode *node=root;
        for(auto c:key){
            if(node->next[c-'a']==nullptr)
                node->next[c-'a']=new TrieNode();
            node=node->next[c-'a'];
            node->val+=delta;
        }
    }
    
    int sum(string prefix) {
        TrieNode* node=root;
        for(auto c:prefix){
            if(node->next[c-'a']==nullptr)
                return 0;
            else
                node=node->next[c-'a'];
        }
        return node->val;
    }
private:
    TrieNode *root;
    unordered_map<string,int> cnt;
};
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

鸡蛋糕跟你嘴角果酱我都想要尝

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值