实现一个 MapSum 类里的两个方法,insert
和 sum
。
对于方法 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;
}
};
或者用map
从prefix
开始的字符串判断,这样更快,并且因为按照字典序排序,只要有一个不满足,后面所有的都不满足,所以时间是最快的
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;
}
};