Open azl397985856 opened 2 years ago
class TrieNode:
def __init__(self):
self.count = 0
self.val = 0
self.children = {}
self.isWord = False
class MapSum:
def __init__(self):
self.root = TrieNode()
def searchVal(self, key: str) -> int:
cur = self.root
for ch in key:
if ch not in cur.children:
return 0
cur = cur.children[ch]
if cur.isWord:
return cur.val
else:
return 0
def insert(self, key: str, val: int) -> None:
cur = self.root
oldVal = self.searchVal(key)
for ch in key:
if ch not in cur.children:
cur.children[ch] = TrieNode()
cur = cur.children[ch]
cur.count = cur.count - oldVal + val
cur.val = val
cur.isWord = True
def sum(self, prefix: str) -> int:
cur = self.root
for ch in prefix:
if ch not in cur.children:
return 0
cur = cur.children[ch]
return cur.count
# Your MapSum object will be instantiated and called as such:
# obj = MapSum()
# obj.insert(key,val)
# param_2 = obj.sum(prefix)
var MapSum = function () { this.map = new Map() }
MapSum.prototype.insert = function (key, val) { this.map.set(key, val) }
MapSum.prototype.sum = function (prefix) { let res = 0 for (const s of this.map.keys()) { if (s.startsWith(prefix)) { res += this.map.get(s) } } return res }
class MapSum { Map<String, Integer> map;
public MapSum() {
map = new HashMap<>();
}
public void insert(String key, int val) {
map.put(key,val);
}
public int sum(String prefix) {
int res = 0;
for (String s : map.keySet()) {
if (s.startsWith(prefix)) {
res += map.get(s);
}
}
return res;
}
}
https://leetcode.com/problems/map-sum-pairs/
HashMap
class MapSum {
Map<String, Integer> map;
public MapSum() {
this.map = new HashMap<>();
}
public void insert(String key, int val) {
map.put(key, val);
}
public int sum(String prefix) {
int res = 0;
for(String s: map.keySet()){
if(s.startsWith(prefix)){
res += map.get(s);
}
}
return res;
}
}
/**
Trie
class MapSum {
TrieNode root;
public MapSum() {
this.root = new TrieNode();
}
public void insert(String key, int val) {
int oldValue = search(key);
int delta = val - oldValue;
TrieNode node = this.root;
for(char c: key.toCharArray()){
if(node.children[c - 'a'] == null){
node.children[c - 'a'] = new TrieNode();
}
node.children[c - 'a'].count += delta;
node = node.children[c - 'a'];
}
node.isKey = true;
node.val = val;
}
private int search(String key){
TrieNode node = this.root;
for(char c: key.toCharArray()){
if(node.children[c - 'a'] == null){
return 0;
}
node = node.children[c - 'a'];
}
return node.isKey? node.val: 0;
}
public int sum(String prefix) {
TrieNode node = this.root;
for(char c: prefix.toCharArray()){
if(node.children[c - 'a'] == null){
return 0;
}
node = node.children[c - 'a'];
}
return node.count;
}
}
class TrieNode{ int val; // the value of the key if this TrieNode is the end of a key (this.isKey == true) int count; // the prefix count of all the keys if this TrieNode is part of the prefix of any keys boolean isKey; // whether this TrieNode is the end of a key TrieNode[] children; // the next TrieNodes of this TrieNode public TrieNode(){ this.val = 0; this.count = 0; this.isKey = false; this.children = new TrieNode[26]; } }
/**
key
and val
values combined.利用哈希表来存储健值对,并做最后的统计。
class MapSum {
unordered_map<string, int> dict;
public:
MapSum() {
}
void insert(string key, int val) {
dict[key] = val;
}
int sum(string prefix) {
int sum = 0;
for(auto& key:dict)
{
if(key.first.find(prefix)!=string::npos && key.first.find(prefix)==0)
{
sum += key.second;
}
}
return sum;
}
};
/**
##Complexity:
Time: insert:O(1), sum:O(n)
Space:O(n)
https://leetcode.com/problems/map-sum-pairs/
-trie
trie + hashmap
class MapSum:
def __init__(self):
self.map = {}
self.root = {}
self.score = "$"
def insert(self, key: str, val: int) -> None:
delta = val - self.map.get(key, 0)
self.map[key] = val
cur = self.root
cur[self.score] = cur[self.score] + delta if self.score in cur else delta
for char in key:
if char not in cur:
cur[char] = {}
cur = cur[char]
cur[self.score] = cur[self.score] + delta if self.score in cur else delta
def sum(self, prefix: str) -> int:
cur = self.root
for char in prefix:
if char not in cur:
return 0
cur = cur[char]
return cur[self.score]
时间复杂度: O(K) K is the length of each insert. 空间复杂度:O(N)
思路 方法一、哈希表 方法二、Trie Tree + Hash
复杂度分析:
代码(C++):
方法二、
struct TrieNode {
TrieNode* children[26];
bool is_str = false;
};
class MapSum {
public:
/** Initialize your data structure here. */
MapSum() {
root = new TrieNode();
}
void insert(string key, int val) {
TrieNode* p = root;
for (auto &k : key) {
int i = k - 'a';
if (!p->child[i]) p->child[i] = new TrieNode();
p = p->child[i];
}
p->is_str = true;
mp[key] = val;
}
int sum(string prefix) {
int sum = 0;
for (auto it = mp.begin(); it != mp.end(); ++it) {
int pos = it->first.find(prefix);
if (pos != string::npos && pos == 0)// found a key starts with the prefix
sum += it->second;
}
return sum;
}
private:
TrieNode* root;
unordered_map<string, int> mp;
};
/**
* Your MapSum object will be instantiated and called as such:
* MapSum* obj = new MapSum();
* obj->insert(key,val);
* int param_2 = obj->sum(prefix);
*/
class MapSum {
class TrieNode {
int val = 0;
TrieNode[] next = new TrieNode[26];
}
TrieNode root;
Map<String, Integer> map;
public MapSum() {
root = new TrieNode();
map = new HashMap<>();
}
public void insert(String key, int val) {
int delta = val - map.getOrDefault(key, 0);
map.put(key, val);
TrieNode node = root;
for (char c : key.toCharArray()) {
if (node.next[c - 'a'] == null) {
node.next[c - 'a'] = new TrieNode();
}
node = node.next[c - 'a'];
node.val += delta;
}
}
public int sum(String prefix) {
TrieNode node = root;
for (char c : prefix.toCharArray()) {
if (node.next[c - 'a'] == null) {
return 0;
}
node = node.next[c - 'a'];
}
return node.val;
}
}
时间复杂度: O(N)
空间复杂度:O(N * K)
前缀树
class TrieNode:
def __init__(self):
self.isKey = False
self.value = 0
self.children = {}
class MapSum:
def __init__(self):
self.root = TrieNode()
def insert(self, key: str, val: int) -> None:
node = self.root
for ch in key:
if ch not in node.children:
node.children[ch] = TrieNode()
node = node.children[ch]
node.value = val
node.isKey = True
def sum(self, prefix: str) -> int:
def dfs(node):
if not node:
return 0
if node.isKey:
self.res += node.value
for key in node.children:
dfs(node.children[key])
node = self.root
self.res = 0
for ch in prefix:
if ch not in node.children:
return 0
node = node.children[ch]
dfs(node)
return self.res
时间复杂度:insert O(n) sum O(m^n)
空间复杂度:O(m*n)
mapping想起hashmap
class MapSum {
public:
MapSum() {
}
void insert(string key, int val) {
map[key] = val;
}
int sum(string prefix) {
int sum = 0;
for (auto& [k, v]: map) {
if (k.substr(0, prefix.size()) == prefix) {
sum += v;
}
}
return sum;
}
private:
unordered_map<string, int> map;
};
class TrieNode:
def __init__(self):
self.children={}
self.value=None
class MapSum:
def __init__(self):
self.root=TrieNode()
self.key_values={}
def insert(self, key: str, val: int) -> None:
old_value=self.key_values[key] if key in self.key_values else 0
self.key_values[key]=val
current_node=self.root
for c in key:
if c not in current_node.children:
current_node.children[c]=TrieNode()
current_node.children[c].value=val
else:
current_node.children[c].value+=val-old_value
current_node=current_node.children[c]
def sum(self, prefix: str) -> int:
current_node=self.root
for c in prefix:
if c not in current_node.children:
return 0
current_node=current_node.children[c]
return current_node.value
Insert: O(n) length of key
sum:O(n) length of prefix
Insert: O(n)
var MapSum = function () {
this.trieArr = new Array(10000); //二维数组的行,[行i][列j]=x 第i个节点指出的边上字符为字符集中的j,指向值为x的节点,
this.finishCount = {};//某节点被标记为结束点时对应value,相同则被替换
this.index = 0;//记录有多少个节点
};
/**
* @param {string} key
* @param {number} val
* @return {void}
*/
MapSum.prototype.insert = function (key, val) {
let keyArr = key.split('');
let p = 0;//结束节点
for (let i = 0; i < keyArr.length; i++) {
if (!Array.isArray(this.trieArr[p])) this.trieArr[p] = []
let now = keyArr[i].charCodeAt() - 'a'.charCodeAt()
if (!this.trieArr[p][now]) {
this.trieArr[p][now] = ++this.index;//插入操作
}
p = this.trieArr[p][now];//结束节点后移
}
this.finishCount[p] = val;
};
/**
* @param {string} prefix
* @return {number}
*/
MapSum.prototype.sum = function (prefix) {
let p = 0;
const prefixArr = prefix.split('');
let dfs = (p) => {
let sum=0;//每个dfs的初始值 不然加到全局变量上 乱套
if (this.finishCount[p]) {
sum = this.finishCount[p]
}
if (this.trieArr[p]) {
for (let i = 0; i < this.trieArr[p].length; i++) {
if (this.trieArr[p][i]) {
sum += dfs(this.trieArr[p][i])
}
}
}
return sum;
}
for (let i = 0; i < prefixArr.length; i++) {
let now = prefixArr[i].charCodeAt() - 'a'.charCodeAt()
if (!this.trieArr[p] || !this.trieArr[p][now]) return 0;
p = this.trieArr[p][now]
}
console.log(this.finishCount)
return dfs(p);
//遍历完输入前缀如果后面可能有值,则继续遍历最后一个节点的所有后续节点
};
时间复杂度:O(n) O(nmc) 空间复杂度:O(nmc)
class MapSum {
/**
* Initialize your data structure here.
*/
constructor() { // Space: O(n)
this.map = new Map();
this.root = new TrieNode();
}
/**
* @param {string} key
* @param {number} val
* @return {void}
*/
insert(key, val) { // Time: O(k), k = len(key)
const delta = val - (this.map.get(key) || 0);
this.map.set(key, val);
let node = this.root;
node.score += delta;
for (const char of key) {
if (!node.children.has(char)) {
node.children.set(char, new TrieNode());
}
node = node.children.get(char);
node.score += delta;
}
}
/**
* @param {string} prefix
* @return {number}
*/
sum(prefix) { // Time: O(k), k = len(prefix)
let node = this.root;
for (const char of prefix) {
node = node.children.get(char);
if (!node) return 0;
}
return node.score;
}
}
function TrieNode() {
this.children = new Map();
this.score = 0;
}
该题使用前缀树模板即可。
class MapSum { private class TrieNode{ int preCount; TrieNode[] children; TrieNode(){ children = new TrieNode[26]; preCount = 0;//记录每个节点累计的值 } } private TrieNode trienode; private HashMap<String,Integer> hash; public MapSum() { trienode = new TrieNode(); hash = new HashMap<>(); } public void insert(String key, int val) { int size = key.length(); TrieNode cur_node = trienode; int old = hash.getOrDefault(key,0); hash.put(key,val); for(int i = 0;i<size;i++){ if(cur_node.children[key.charAt(i)-'a']==null){ cur_node.children[key.charAt(i)-'a']=new TrieNode(); } cur_node = cur_node.children[key.charAt(i)-'a']; cur_node.preCount = cur_node.preCount+val-old; } } public int sum(String prefix) { int size = prefix.length(); TrieNode cur = trienode; for(int i=0;i<size;i++){ if(cur.children[prefix.charAt(i)-'a']==null){ return 0; } cur = cur.children[prefix.charAt(i)-'a']; } return cur.preCount; } }
class TrieNode:
def __init__(self):
self.precount = 0
self.val = 0
self.children = {}
class MapSum:
def __init__(self):
self.root = TrieNode()
def insert(self, key: str, val: int) -> None:
node = self.root
for ch in key:
if ch not in node.children:
node.children[ch] = TrieNode()
node = node.children[ch]
node.precount += 1
node.val = val
def dfs(self, node: TrieNode):
count = 0
for child in node.children:
if child:
count += self.dfs(node.children[child])
return count + node.val
def sum(self, prefix: str) -> int:
node = self.root
for ch in prefix:
if ch not in node.children:
return 0
node = node.children[ch]
if node.precount > 0:
return self.dfs(node)
class MapSum {
private Map<String, Integer> map = null;
public MapSum() {
map = new HashMap<String, Integer>();
}
public void insert(String key, int val) {
map.put(key, val);
}
public int sum(String prefix) {
int count = 0;
for(String k: map.keySet()) {
if(k.startsWith(prefix)) {
count += map.get(k);
}
}
return count;
}
class MapSum:
def __init__(self):
self.map = {}
def insert(self, key: str, val: int) -> None:
self.map[key] = val
def sum(self, prefix: str) -> int:
count = 0
for key in self.map:
if key.startswith(prefix):
count += self.map[key]
return count
class 键值映射_677 {
Node root = new Node();
Map<String, Integer> sumMap = new HashMap<>();
public MapSum() {
}
public void insert(String key, int val) {
int add = val;
Integer old = sumMap.get(key);
if(old != null) add -= old;
Node node = root;
for(int i = 0; i< key.length(); i++) {
int c = key.charAt(i) - 'a';
if(node.next[c] == null) node.next[c] = new Node();
node = node.next[c];
node.sum += add;
}
node.val = val;
sumMap.put(key, val);
}
public int sum(String prefix) {
Node node = root;
for(int i = 0; i< prefix.length(); i++) {
int c = prefix.charAt(i) - 'a';
if(node.next[c] == null) return 0;
node = node.next[c];
}
// 也可以不用sumMap 在这里向下递归求和
return node.sum;
}
static class Node{
Node[] next = new Node[26];
int val;
int 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);
*/
class 键值映射_677 {
Node root = new Node();
Map<String, Integer> sumMap = new HashMap<>();
public MapSum() {
}
public void insert(String key, int val) {
int add = val;
Integer old = sumMap.get(key);
if(old != null) add -= old;
Node node = root;
for(int i = 0; i< key.length(); i++) {
int c = key.charAt(i) - 'a';
if(node.next[c] == null) node.next[c] = new Node();
node = node.next[c];
node.sum += add;
}
node.val = val;
sumMap.put(key, val);
}
public int sum(String prefix) {
Node node = root;
for(int i = 0; i< prefix.length(); i++) {
int c = prefix.charAt(i) - 'a';
if(node.next[c] == null) return 0;
node = node.next[c];
}
// 也可以不用sumMap 在这里向下递归求和
return node.sum;
}
static class Node{
Node[] next = new Node[26];
int val;
int 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);
*/
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;
};
class TrieNode { constructor() { this.val = 0; this.next = new Array(26).fill(0); } }
var MapSum = function() { this.root = new TrieNode(); this.map = new Map();
};
MapSum.prototype.insert = function(key, val) { const delta = val - (this.map.get(key) || 0); this.map.set(key, val); let node = this.root; for (const c of key) { if (node.next[c.charCodeAt() - 'a'.charCodeAt()] === 0) { node.next[c.charCodeAt() - 'a'.charCodeAt()] = new TrieNode(); } node = node.next[c.charCodeAt() - 'a'.charCodeAt()]; node.val += delta; } };
MapSum.prototype.sum = function(prefix) { let node = this.root; for (const c of prefix) { if (node.next[c.charCodeAt() - 'a'.charCodeAt()] === 0) { return 0; } node = node.next[c.charCodeAt() - 'a'.charCodeAt()]; } return node.val; };
class MapSum: def init(self): self.d = {}
def insert(self, key: str, val: int) -> None:
self.d[key] = val
def sum(self, prefix: str) -> int:
res=0
for s in self.d:
if s.startswith(prefix):
res+=self.d[s]
return res
class MapSum(object):
def __init__(self):
self.data ={}
def insert(self, key, val):
"""
:type key: str
:type val: int
:rtype: None
"""
self.data[key] = val
def sum(self, prefix):
"""
:type prefix: str
:rtype: int
"""
ans = 0
for key in self.data.keys():
if key.startswith(prefix):
ans += self.data[key]
return ans
# Your MapSum object will be instantiated and called as such:
# obj = MapSum()
# obj.insert(key,val)
# param_2 = obj.sum(prefix)
时间复杂度:插入O(1),求和O(n*s)n为key个数,s为前缀长度 空间复杂度:O(n),n为不重复的key个数
type MapSum map[string]int
func Constructor() MapSum {
return MapSum{}
}
func (m MapSum) Insert(key string, val int) {
m[key] = val
}
func (m MapSum) Sum(prefix string) int {
sum := 0
for s, v := range m {
if strings.HasPrefix(s, prefix){
sum += v
}
}
return sum
}
title: "Day 74 677. 键值映射" date: 2021-11-22T11:45:25+08:00 tags: ["Leetcode", "c++", "Trie"] categories: ["91-day-algorithm"] draft: true
实现一个 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、最简单方法直接使用cpp的四大容器组件即可中,但是由于是学习trie树的使用,所以使用tire来构建
const int N = 3000;
int ans[N][26];
int cnt[N];
int idx = 0;
class MapSum {
public:
MapSum() {
memset(ans, 0, sizeof ans); // 也可以使用动态数组进行i
memset(cnt, 0, sizeof cnt);
}
void insert(string key, int val) {
int p = 0;
for (auto &i : key)
{
int q = i - 'a';
if (!ans[p][q]) ans[p][q] = ++idx;
p = ans[p][q];
}
cnt[p] = val;
}
int sum(string prefix) {
int p = 0;
for (auto &i : prefix)
{
int q = i - 'a';
if (!ans[p][q]) return 0;
p = ans[p][q];
}
return dfs(p);
}
int dfs(int p) {
if (!p) return 0;
int res = cnt[p];
for (int i = 0; i < 26; ++i) {
res += dfs(ans[p][i]);
}
return res;
}
};
/**
* Your MapSum object will be instantiated and called as such:
* MapSum* obj = new MapSum();
* obj->insert(key,val);
* int param_2 = obj->sum(prefix);
*/
class MapSum {
unordered_map<string, int> dict;
public:
/** Initialize your data structure here. */
MapSum() {
}
void insert(string key, int val) {
if (dict.count(key) == 0)
dict[key] = val;
else dict[key] = val;
}
int sum(string prefix) {
int sum = 0;
for (auto& kvp : dict)
{
if (kvp.first.find(prefix) != string::npos && kvp.first.find(prefix) == 0) /* 需要是前缀, 而不仅仅是子串 */
sum += kvp.second;
}
return sum;
}
}
class MapSum {
class TrieNode {
int val = 0;
TrieNode[] next = new TrieNode[26];
}
TrieNode root;
Map<String, Integer> map;
public MapSum() {
root = new TrieNode();
map = new HashMap<>();
}
public void insert(String key, int val) {
int delta = val - map.getOrDefault(key, 0);
map.put(key, val);
TrieNode node = root;
for (char c : key.toCharArray()) {
if (node.next[c - 'a'] == null) {
node.next[c - 'a'] = new TrieNode();
}
node = node.next[c - 'a'];
node.val += delta;
}
}
public int sum(String prefix) {
TrieNode node = root;
for (char c : prefix.toCharArray()) {
if (node.next[c - 'a'] == null) {
return 0;
}
node = node.next[c - 'a'];
}
return node.val;
}
}
class MapSum:
def __init__(self):
self.m = {}
def insert(self, key, val):
self.m[key] = val
def sum(self, prefix):
count = 0
for key in self.m:
if key.startswith(prefix):
count += self.m[key]
return count
class MapSum:
def __init__(self):
self.m = {}
def insert(self, key, val):
self.m[key] = val
def sum(self, prefix):
count = 0
for key in self.m:
if key.startswith(prefix):
count += self.m[key]
return count
struct TrieNode {
int val;
TrieNode *next[26];
TrieNode() {
this->val = 0;
for (int i = 0; i < 26; ++i) {
this->next[i] = nullptr;
}
}
};
class MapSum {
private:
TrieNode *root;
unordered_map<string, int> count;
public:
MapSum() {
this->root = new TrieNode();
}
void insert(string key, int val) {
int delta = val;
if (count.count(key)) {
delta -= count[key];
}
count[key] = val;
TrieNode * node = root;
for (auto &ch : key) {
if (node->next[ch - 'a'] == nullptr) {
node->next[ch - 'a'] = new TrieNode();
}
node = node->next[ch - 'a'];
node->val += delta;
}
}
int sum(string prefix) {
TrieNode * node = root;
for (auto &ch : prefix) {
if (node->next[ch - 'a'] == nullptr) {
return 0;
}
else {
node = node->next[ch - 'a'];
}
}
return node->val;
}
};
from collections import defaultdict
class MapSum:
def __init__(self):
self.tree=defaultdict(int)
def insert(self, key: str, val: int) -> None:
tmp=self.tree
memo=[]
index=0
for i in key:
if i not in tmp:
break
tmp=tmp[i]
memo.append(tmp)
index+=1
if index==len(key) and tmp['*']:
prev=tmp['*']
for i in memo:
i['#']+=val-prev
tmp['*']=val
return
for i in memo:
i['#']+=val
for i in range(index,len(key)):
tmp[key[i]]=defaultdict(int)
tmp=tmp[key[i]]
tmp['#']+=val
tmp['*']=val
def sum(self, prefix: str) -> int:
tmp=self.tree
for i in prefix:
if i not in tmp:
return 0
tmp=tmp[i]
return tmp['#']
/**
* Initialize your data structure here.
*/
var MapSum = function() {
this.map = new Map()
};
/**
* @param {string} key
* @param {number} val
* @return {void}
*/
MapSum.prototype.insert = function(key, val) {
this.map.set(key, val)
};
/**
* @param {string} prefix
* @return {number}
*/
MapSum.prototype.sum = function(prefix) {
let sum = 0;
let keys = [...this.map.keys()];
keys.forEach(key => {
if(key.startsWith(prefix)) {
sum = sum + this.map.get(key)
}
})
return sum
};
/**
* Your MapSum object will be instantiated and called as such:
* var obj = new MapSum()
* obj.insert(key,val)
* var param_2 = obj.sum(prefix)
*/
from collections import defaultdict class MapSum:
def __init__(self):
self.tree=defaultdict(int)
def insert(self, key: str, val: int) -> None:
tmp=self.tree
memo=[]
index=0
for i in key:
if i not in tmp:
break
tmp=tmp[i]
memo.append(tmp)
index+=1
if index==len(key) and tmp['*']:
prev=tmp['*']
for i in memo:
i['#']+=val-prev
tmp['*']=val
return
for i in memo:
i['#']+=val
for i in range(index,len(key)):
tmp[key[i]]=defaultdict(int)
tmp=tmp[key[i]]
tmp['#']+=val
tmp['*']=val
def sum(self, prefix: str) -> int:
tmp=self.tree
for i in prefix:
if i not in tmp:
return 0
tmp=tmp[i]
return tmp['#']
var MapSum = function() {
this.map = new Map();
};
/**
* @param {string} key
* @param {number} val
* @return {void}
*/
MapSum.prototype.insert = function(key, val) {
this.map.set(key,val);
};
/**
* @param {string} prefix
* @return {number}
*/
MapSum.prototype.sum = function(prefix) {
let nums = 0;
let keys = [...this.map.keys()];
keys.forEach(key => {
if(key.startsWith(prefix)){
nums += this.map.get(key);
}
})
return nums;
};
var MapSum = function() {
this.map = {}
this.cache = {}
};
MapSum.prototype.insert = function(key, val) {
const detla = val - (this.cache[key] || 0)
this.cache[key] = val
let map = this.map
for (let i = 0; i < key.length; i++) {
if (map[key[i]]) {
map[key[i]].val += detla
} else {
map[key[i]] = {
val: detla
}
}
map = map[key[i]]
}
};
MapSum.prototype.sum = function(prefix) {
let map = this.map
for (let i = 0; i < prefix.length; i++) {
if (map[prefix[i]] === undefined) {
return 0
}
map = map[prefix[i]]
}
return map.val
};
class MapSum {
HashMap<String, Integer> map = new HashMap<>();
public MapSum() {
}
public void insert(String key, int val) {
map.put(key, val);
}
public int sum(String prefix) {
int sum = 0;
for(String key : map.keySet()){
if(key.startsWith(prefix)) sum += map.get(key);
}
return sum;
}
}
哈希
``
class MapSum {
Map<String, Integer> map;
public MapSum() {
map = new HashMap<>();
}
public void insert(String key, int val) {
map.put(key,val);
}
public int sum(String prefix) {
int res = 0;
for (String s : map.keySet()) {
if (s.startsWith(prefix)) {
res += map.get(s);
}
}
return res;
}
}
时间复杂度:insert 操作时间复杂度为 O(1)。sum 操作时间复杂度为O(NM),其中 N 是插入的key 的数目,M 是给定前缀prefix 的长度。
空间复杂度:O(NM),其中 N 是插入的key 的数目,M 是字符串key 的最大长度
class MapSum:
def __init__(self):
self.root = TrieNode()
self.map = {}
def insert(self, key: str, val: int) -> None:
delta = val
if key in self.map:
delta -= self.map[key]
self.map[key] = val
node = self.root
for c in key:
if node.next[ord(c) - ord('a')] is None:
node.next[ord(c) - ord('a')] = TrieNode()
node = node.next[ord(c) - ord('a')]
node.val += delta
def sum(self, prefix: str) -> int:
node = self.root
for c in prefix:
if node.next[ord(c) - ord('a')] is None:
return 0
node = node.next[ord(c) - ord('a')]
return node.val
class TrieNode:
def __init__(self):
self.val = 0
self.next = [None for _ in range(26)]
# Your MapSum object will be instantiated and called as such:
# obj = MapSum()
# obj.insert(key,val)
# param_2 = obj.sum(prefix)
class MapSum {
private class TrieNode {
TrieNode[] children;
int precount;
public TrieNode() {
children = new TrieNode[26];
precount = 0;
}
}
TrieNode root;
Map<String, Integer> map;
public MapSum() {
root = new TrieNode();
map = new HashMap<>();
}
public void insert(String key, int val) {
int pre = 0;
if (map.containsKey(key)) {
pre = map.get(key);
}
map.put(key, val);
TrieNode node = root;
for (int i = 0; i < key.length(); i++) {
char letter = key.charAt(i);
if (node.children[letter - 'a'] == null) {
node.children[letter - 'a'] = new TrieNode();
}
node = node.children[letter - 'a'];
node.precount += val - pre;
}
}
public int sum(String prefix) {
TrieNode node = root;
for (int i = 0; i < prefix.length(); i++) {
char letter = prefix.charAt(i);
if (node.children[letter - 'a'] == null) {
node.children[letter - 'a'] = new TrieNode();
}
node = node.children[letter - 'a'];
}
return node.precount;
}
}
javascript
/*
* @lc app=leetcode.cn id=677 lang=javascript
*
* [677] 键值映射
*/
// @lc code=start
/**
* Initialize your data structure here.
*/
var MapSum = function() {
this.map = {}
};
/**
* @param {string} key
* @param {number} val
* @return {void}
*/
MapSum.prototype.insert = function(key, val) {
this.map[key] = val
};
/**
* @param {string} prefix
* @return {number}
*/
MapSum.prototype.sum = function(prefix) {
let result = 0
const strArr = Object.keys(this.map)
strArr.forEach(str => {
if (str.startsWith(prefix)) {
result += this.map[str]
}
})
return result
};
/**
* Your MapSum object will be instantiated and called as such:
* var obj = new MapSum()
* obj.insert(key,val)
* var param_2 = obj.sum(prefix)
*/
// @lc code=end
class MapSum {
class TrieNode {
int val = 0;
TrieNode[] next = new TrieNode[26];
}
TrieNode root;
Map<String, Integer> map;
public MapSum() {
root = new TrieNode();
map = new HashMap<>();
}
public void insert(String key, int val) {
int delta = val - map.getOrDefault(key, 0);
map.put(key, val);
TrieNode node = root;
for (char c : key.toCharArray()) {
if (node.next[c - 'a'] == null) {
node.next[c - 'a'] = new TrieNode();
}
node = node.next[c - 'a'];
node.val += delta;
}
}
public int sum(String prefix) {
TrieNode node = root;
for (char c : prefix.toCharArray()) {
if (node.next[c - 'a'] == null) {
return 0;
}
node = node.next[c - 'a'];
}
return node.val;
}
}
https://leetcode-cn.com/problems/map-sum-pairs/
Trie+DFS
class MapSum:
def __init__(self):
self.trie = {}
self.val = 0
def insert(self, key: str, val: int) -> None:
cur = self.trie
for k in key:
if k not in cur:
cur[k] = {}
cur = cur[k]
else:
cur = cur[k]
cur['#'] = val
def sum(self, prefix: str) -> int:
cur = self.trie
for pre in prefix:
if pre not in cur:
return 0
else:
cur = cur[pre]
return self.dfs(cur)
def dfs(self, cur: dict) -> int:
ans = 0
for k in cur:
if k == '#':
ans += cur[k]
else:
ans += self.dfs(cur[k])
return ans
# Your MapSum object will be instantiated and called as such:
# obj = MapSum()
# obj.insert(key,val)
# param_2 = obj.sum(prefix)
Algo
- This can be a example of using prefix tree, see another note
class MapSum:
def __init__(self):
self.m = {}
def insert(self, key, val):
self.m[key] = val
def sum(self, prefix):
count = 0
for key in self.m:
if key.startswith(prefix):
count += self.m[key]
return count
# Your MapSum object will be instantiated and called as such:
# obj = MapSum()
# obj.insert(key,val)
# param_2 = obj.sum(prefix)
class MapSum {
class TrieNode {
int val = 0;
TrieNode[] next = new TrieNode[26];
}
TrieNode root;
Map<String, Integer> map;
public MapSum() {
root = new TrieNode();
map = new HashMap<>();
}
public void insert(String key, int val) {
int delta = val - map.getOrDefault(key, 0);
map.put(key, val);
TrieNode node = root;
for (char c : key.toCharArray()) {
if (node.next[c - 'a'] == null) {
node.next[c - 'a'] = new TrieNode();
}
node = node.next[c - 'a'];
node.val += delta;
}
}
public int sum(String prefix) {
TrieNode node = root;
for (char c : prefix.toCharArray()) {
if (node.next[c - 'a'] == null) {
return 0;
}
node = node.next[c - 'a'];
}
return node.val;
}
}
class MapSum {
Map<String, Integer> map;
public MapSum() {
map = new HashMap<>();
}
public void insert(String key, int val) {
map.put(key,val);
}
public int sum(String prefix) {
int res = 0;
for (String s : map.keySet()) {
if (s.startsWith(prefix)) {
res += map.get(s);
}
}
return res;
}
}
class MapSum:
def __init__(self):
self.hashmap = {}
def insert(self, key: str, val: int) -> None:
self.hashmap[key] = val
def sum(self, prefix: str) -> int:
count = 0
for key in self.hashmap:
if key.startswith(prefix):
count += self.hashmap[key]
return count
Time: O(1) Space: O(n)
class MapSum:
def __init__(self):
self.map = {}
def insert(self, key: str, val: int) -> None:
self.map[key] = val
def sum(self, prefix: str) -> int:
res = 0
for key,val in self.map.items():
if key.startswith(prefix):
res += val
return res
// 11-22 cpp 哈希
class MapSum {
public:
map<string, int> mp;
MapSum() {
}
void insert(string key, int val) {
mp[key] = val;
}
int sum(string prefix) {
int res = 0;
string s;
for (auto it : mp) {
s = it.first;
if (s.find(prefix)==0) {
res += it.second;
}
}
return res;
}
};
class TrieNode:
def __init__(self):
self.count = 0
self.children = {}
class MapSum:
def __init__(self):
self.root = TrieNode()
def insert(self, key: str, val: int) -> None:
node = self.root
for k in key:
if k not in node.children:
node.children[k] = TrieNode()
node = node.children[k]
node.count = val
def sum(self, prefix: str) -> int:
node = self.root
for k in prefix:
if k not in node.children:
return 0
node = node.children[k]
return node.count + self.dfs(node)
def dfs(self, node: TrieNode) -> int:
summ = 0
for child in node.children:
summ += child.count
return summ
class MapSum:
def __init__(self):
self.hashmap = {}
def insert(self, key: str, val: int) -> None:
self.hashmap[key] = val
def sum(self, prefix: str) -> int:
count = 0
for key in self.hashmap:
if key.startswith(prefix):
count += self.hashmap[key]
return count
677. 键值映射
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/map-sum-pairs
前置知识
题目描述
实现一个 MapSum 类里的两个方法,insert 和 sum。
对于方法 insert,你将得到一对(字符串,整数)的键值对。字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。
对于方法 sum,你将得到一个表示前缀的字符串,你需要返回所有以该前缀开头的键的值的总和。
示例 1:
输入: insert("apple", 3), 输出: Null 输入: sum("ap"), 输出: 3 输入: insert("app", 2), 输出: Null 输入: sum("ap"), 输出: 5