LeetCode 677.键值映射

94 篇文章 0 订阅

实现一个 MapSum 类里的两个方法,insertsum

对于方法 insert,你将得到一对(字符串,整数)的键值对。字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。

对于方法 sum,你将得到一个表示前缀的字符串,你需要返回所有以该前缀开头的键的值的总和。

示例 1:

输入: insert("apple", 3), 输出: Null
输入: sum("ap"), 输出: 3
输入: insert("app", 2), 输出: Null
输入: sum("ap"), 输出: 5

字典树

思路:

把给定串的最后一个字符赋值val,递归求解以给定串为前缀的所有串的值总和

不过这样是比较慢的

class MapSum
{
private:
    static const int maxn = 10000;
    int tot = 1, trie[maxn][26], cnt[maxn];

    int sumVal(int pos) //递归求解以给定串为前缀的所有串值
    {
        int ans = 0;
        if (cnt[pos])               //是一个字符串的终点,加上其值
            ans += cnt[pos];
        for (int i = 0; i < 26; ++i)//递归求解其所有子串
            if (trie[pos][i])
                ans += sumVal(trie[pos][i]);
        return ans;
    }
public:
    /** Initialize your data structure here. */
    MapSum()
    {
        memset(trie, 0, sizeof(trie));
    }
    void insert(string key, int val)
    {
        int p = 1;
        for (char c : key)
        {
            int ch = c - 'a';
            if (trie[p][ch] == 0)
                trie[p][ch] = ++tot;
            p = trie[p][ch];
        }
        cnt[p] = val;//字符串的终点,赋值
    }

    int sum(string prefix)
    {
        int p = 1;
        for (char c : prefix)
        {
            p = trie[p][c - 'a'];
            if (p == 0)//没有这个串的值,返回0
                return 0;
        }
        return sumVal(p); //找到前缀字符的最后一个位置,递归求解
    }
};

/**
 * Your MapSum object will be instantiated and called as such:
 * MapSum* obj = new MapSum();
 * obj->insert(key,val);
 * int param_2 = obj->sum(prefix);
 */

哈希

直接用哈希表存储键值,然后遍历哈希表,如果str.substr == prefix那么就加入答案

class MapSum
{
private:
    unordered_map<string, int> m;
public:
    /** Initialize your data structure here. */
    MapSum(){
    }

    void insert(string key, int val)
    {
        m[key] = val;
    }

    int sum(string prefix)
    {
        int psize = prefix.length(), ans = 0;
        for (auto it = m.begin(); it != m.end(); ++it)
        {
            string str = it->first;
            if (psize > str.length())
                continue;
            if (str.substr(0, psize) == prefix)
                ans += m[str];
        }
        return ans;
    }
};

或者用mapprefix开始的字符串判断,这样更快,并且因为按照字典序排序,只要有一个不满足,后面所有的都不满足,所以时间是最快的

class MapSum
{
private:
    map<string, int> m;
public:
    /** Initialize your data structure here. */
    MapSum(){
    }

    void insert(string key, int val)
    {
        m[key] = val;
    }

    int sum(string prefix)
    {
        int psize = prefix.length(), ans = 0;
        auto it = m.lower_bound(prefix);//第一个大于等于的下标
        while (it != m.end() && it->first.substr(0, psize) == prefix)
        {
            ans += it->second;
            ++it;
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值