677 键值映射

题目描述:
实现一个 MapSum 类,支持两个方法,insert 和 sum:
MapSum() 初始化 MapSum 对象
void insert(String key, int val) 插入 key-val 键值对,字符串表示键 key ,整数表示值 val 。如果键 key 已经存在,那么原来的键值对将被替代成新的键值对。
int sum(string prefix) 返回所有以该前缀 prefix 开头的键 key 的值的总和。

示例:
输入:
[“MapSum”, “insert”, “sum”, “insert”, “sum”]
[[], [“apple”, 3], [“ap”], [“app”, 2], [“ap”]]
输出:
[null, null, 3, null, 5]
解释:
MapSum mapSum = new MapSum();
mapSum.insert(“apple”, 3);
mapSum.sum(“ap”); // return 3 (apple = 3)
mapSum.insert(“app”, 2);
mapSum.sum(“ap”); // return 5 (apple + app = 3 + 2 = 5)

提示:
1 <= key.length, prefix.length <= 50
key 和 prefix 仅由小写英文字母组成
1 <= val <= 1000
最多调用 50 次 insert 和 sum

方法1:
主要思路:解题汇总链接
(1)使用前缀树;
(2)对于前缀树的每个前缀存储该前缀下的所有的结点之和;
(3)为了能够在插入某个键值时,快速更新前缀树的各个结点之和,使用unordered_map<string,int>存储键对应的值,先判读存在性,再根据此次对应的值,进行更新,算出实际需要插入的值,再对前缀树进行遍历更新;

class MapSum {
public:
    struct Node{
        vector<Node*> next;//各个结点的指针
        vector<int>val;//各个指针下的路径的前缀和
        Node(){
            val=vector<int>(26,0);
            next=vector<Node*>(26,NULL);
        }
    };
    /** Initialize your data structure here. */
    Node* root;
    unordered_map<string,int> mp;//存储键值
    MapSum() {
        root=new Node();
    }
    
    void insert(string key, int val) {
        Node* cur=root;
        if(mp.count(key)){//判断键的存在性,并进行键和值的更新
            int tmp=val;
            val-=mp[key];
            mp[key]=tmp;
        }
        else{
            mp[key]=val;
        }
        //更新前缀树
        for(char&ch:key){
            if(cur->next[ch-'a']==NULL){
                cur->next[ch-'a']=new Node();    //若不存在,则建立新的结点
            }
            cur->val[ch-'a']+=val;
            cur=cur->next[ch-'a'];
        }
    }
    //找给出的前缀的和
    int sum(string prefix) {
        int sum=0;
        Node* cur=root;
        for(char&ch:prefix){
            sum=cur->val[ch-'a'];//更新该值
            cur=cur->next[ch-'a'];
            if(cur==NULL){//若已经是空,则终止循环
                break;
            }
        }
        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);
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值