leetcode-pp / 91alg-5-daily-check

91 天学算法第五期打卡
55 stars 14 forks source link

【Day 74 】2021-11-22 - 677. 键值映射 #93

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

677. 键值映射

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/map-sum-pairs

前置知识

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

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

示例 1:

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

Yufanzh commented 2 years ago

Algorithm in python3

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)

Complexity Analysis

shibingchao123 commented 2 years ago

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 }

JinhMa commented 2 years ago

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;
}

}

ginnydyy commented 2 years ago

Problem

https://leetcode.com/problems/map-sum-pairs/

Notes

Solution

/**

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]; } }

/**

Complexity

V-Enzo commented 2 years ago

思路

  1. 利用哈希表来存储健值对,并做最后的统计。

    
    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;
    }
    };

/**

ai2095 commented 2 years ago

677. Map Sum Pairs

https://leetcode.com/problems/map-sum-pairs/

Topics

-trie

思路

trie + hashmap

代码 Python

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)

falconruo commented 2 years ago

思路 方法一、哈希表 方法二、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);
 */
mannnn6 commented 2 years ago

代码

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)

Neal0408 commented 2 years ago

思路

前缀树

代码

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)

asterqian commented 2 years ago

思路

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;
};

Time Complexity: O(1) for insert, O(map.size()*prefix.size()) for sum

Space Complexity: O(number of keys*length of key)

chen445 commented 2 years ago

代码

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

复杂度

Time:

Insert: O(n) length of key
sum:O(n) length of prefix

Space:

Insert: O(n)

july-aha commented 2 years ago
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)

kennyxcao commented 2 years ago

677. Map Sum Pairs

Intuition

Code

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;
}

Complexity Analysis

Zhang6260 commented 2 years ago

JAVA版本

该题使用前缀树模板即可。

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;
   }
}

时间复杂度:O(n)

空间复杂度:O(n)

Zhi22 commented 2 years ago

思路:前缀树

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)
machuangmr commented 2 years ago

代码

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;
    }

复杂度

RonghuanYou commented 2 years ago
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
carterrr commented 2 years ago

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);
 */
carterrr commented 2 years ago

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);
 */
zszs97 commented 2 years ago

开始刷题

题目简介

【Day 74 】2021-11-22 - 677. 键值映射

思路

题目代码

代码块

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;
};

复杂度

L-SUI commented 2 years ago

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; };

jocelinLX commented 2 years ago

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
biscuit279 commented 2 years ago

思路:还行表

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个数

guangsizhongbin commented 2 years ago
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

}
chaggle commented 2 years ago

title: "Day 74 677. 键值映射" date: 2021-11-22T11:45:25+08:00 tags: ["Leetcode", "c++", "Trie"] categories: ["91-day-algorithm"] draft: true


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、最简单方法直接使用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);
 */

复杂度

hellowxwworld commented 2 years ago
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;
    }
}
HouHao1998 commented 2 years ago
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;
    }
}
Toms-BigData commented 2 years ago

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
yyangeee commented 2 years ago

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
mokrs commented 2 years ago
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;
    }

};
WeiWri-CC commented 2 years ago
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['#']
winterdogdog commented 2 years ago
/**
 * 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)
 */
CruiseYuGH commented 2 years ago

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['#']
shamworld commented 2 years ago
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;
};
HWFrankFung commented 2 years ago

Codes

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
};
shanrufu commented 2 years ago
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;
    }
}
ymkymk commented 2 years ago

思路

哈希

代码

``


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 的最大长度

wangyifan2018 commented 2 years ago
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)
brainlds commented 2 years ago

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;
}

}

joriscai commented 2 years ago

思路

代码

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

复杂度分析

falsity commented 2 years ago
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;
    }
}
user1689 commented 2 years ago

题目

https://leetcode-cn.com/problems/map-sum-pairs/

思路

Trie+DFS

python3

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)

复杂度分析

相关题目

  1. 待补充
MonkofEast commented 2 years ago

677. Map Sum Pairs

Click Me

Algo

  1. This can be a example of using prefix tree, see another note

Code

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)

Comp

T: O(N)

S: O(1) for insert, O(N*prefix_len) for sum

dongzegithub commented 2 years ago

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;
    }
}
yj9676 commented 2 years ago
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;
    }
}
jz1433 commented 2 years ago

代码

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)

BreezePython commented 2 years ago

代码

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

复杂度

kbfx1234 commented 2 years ago

677. 键值映射

// 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;
    }
};
ChenJingjing85 commented 2 years ago
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
Lydia61 commented 2 years ago
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