Implement a MapSum class with insert, and sum methods.
For the method insert, you’ll be given a pair of (string, integer). The string represents the key and the integer represents the value. If the key already existed, then the original key-value pair will be overridden to the new one.
For the method sum, you’ll be given a string representing the prefix, and you need to return the sum of all the pairs’ value whose key starts with the prefix.
实现一个MapSum类,它有两个方法:
1. insert:插入一个键值对
2. sum:求以某一字符串prefix为前缀的值的和。
方法一:
可以用一个map来记录键值对:当insert(key, value)时,将map[key的前缀及其本身] += value。每次sum返回map[key]就可以。这样做存在的一个问题是,如果insert了两次同样的key,那么两次相应的值都会累加,而不是题意所说的重写value。所以我们需要记录下value的值,这样每个key对应两个值:key本身的值(first)及以key为前缀的值(second)。这样每次sum返回map[key].first + map[key].second即可。map[key的前缀]每次加的值不再是value,而是value-map[key].first。
方法二:
巧妙地利用了map会对key进行排序的特点,insert就是map[key] = value;
sum的话,map.lower_bound(prefix)就可以得到可能以prefix为前缀的最小键值对,然后从这里开始遍历,满足条件便将其累加,不满足条件则可以终止遍历。最后return累加值。
//方法一
class MapSum {
public:
/** Initialize your data structure here. */
MapSum() {
}
void insert(string key, int val) {
int diff = val - counter[key].first;
counter[key].first = val;
int n = key.size();
for (int i = n-1;i > 0;--i){
counter[key.substr(0, i)].second += diff;
}
}
int sum(string prefix) {
return counter[prefix].first + counter[prefix].second;
}
private:
unordered_map<string, pair<int, int>> counter;
};
//方法二
class MapSum {
public:
/** Initialize your data structure here. */
MapSum() {
}
void insert(string key, int val) {
m[key] = val;
}
int sum(string prefix) {
int sum = 0, len = prefix.size();
for (auto it = m.lower_bound(prefix); it != m.end();++it){
if (it->first.substr(0,len) != prefix) break;
sum += it->second;
}
return sum;
}
private:
map<string, int> m;
};