算法设计与分析—键值映射(字典树)

LeetCode题目练习:

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)

来源:力扣(LeetCode)

a) 算法思路
方法一:暴力解法
1、数据存到字典中,每次遍历一个字符串
2、insert 方法:字符串如果不存在字典中就存入字典,存在就替换值
3、sum方法:遍历字典中所有的字符串,如果是前缀则加上值。
代码

class MapSum(object):
    def __init__(self):
        self.dic=dict()
    def insert(self, key, val):
        """
        :type key: str
        :type val: int
        :rtype: None
        """
        self.dic[key]=val
    def sum(self, prefix):
        """
        :type prefix: str
        :rtype: int
        """
        res=0
        length=len(prefix)
        for k,v in self.dic.items():
            if k.startswith(prefix):
                res += v
            # 下面的 注释代码 就是比较字符串是不是他的前缀字符串
            # if length<=len(k):
            #     flag=True
            #     for i in range(length):
            #         if prefix[i]!=k[i]:
            #             flag=False
            #             break
            #     if flag==True:
            #         nums+=v
        return res

方法二:字典树
创建一个类似于树的结构,每一个next结构用字典来表示,这样可以避免空间的浪费
1、存储结构,一个字典树,还需要一个字典map来存储已经存储过的字符串,用来判断该字符是否访问过。
2、insert 方法:首先判断该字符串是否已经存储过,如果没有则依次对没个字符进行插入到next字典中,并将值赋给这个字符,否则更新将新的值减去原来的旧值,然后依次更新字典树的每个字符的值。
3、sum方法:直接根据字符串的长度查找字典树。返回最后一个字符存储的值。
在这里插入图片描述

class TrieNode: ## 字典树的节点
    def __init__(self,v=0):
        self.val = v
        self.next = dict()

class MapSum(object):
    def __init__(self):
        self.treNode=TrieNode()  ##用来构造字典树
        self.map={
    
    }  ##用来存储已经访问过得字符串
    def insert(self, key, val):
        """
        :type key: str
        :type val: int
        :rtype: None
        """
        value=val  # 用来更新字符值
        if key in self.map: 
            value=val-self.map[key]
        self.map[key]=val
        node = self.treNode
        for c in key:
            if not node.next.get(c,0):  #判断是否存在该字符,不存在则新建
                node.next[c]=TrieNode()
            node = node.next[c]
            node.val += value

    def sum(self, prefix):
        """
        :type prefix: str
        :rtype: int
        """
        node = self.treNode
        for c in prefix:
            if node.next.get(c,0):
                node = node.next[c]
            else:
                return 0
        return node.val

猜你喜欢

转载自blog.csdn.net/qq_39740279/article/details/121315349