677. 键值映射

103 阅读2分钟

实现一个 MapSum 类里的两个方法,insert 和 sum。

  • 对于方法 insert,你将得到一对(字符串,整数)的键值对。字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。
  • 对于方法 sum,你将得到一个表示前缀的字符串,你需要返回所有以该前缀开头的键的值的总和。

示例 1:

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

题解:这道题的难点在于sum方法,需要返回所有以该前缀开头的键的值的总和,很容易就想到使用上道题的前缀树来做。

class MapSum {

    /** Initialize your data structure here. */
    public MapSum() {

    }

    //自定义前缀树节点
    private class Node{
        //每个节点26个字符
        Node[] childs = new Node[26];
        boolean isLeaf;
        int val;
    }

    //根节点为空
    private Node root = new Node();

    public void insert(String key, int val) {
        insert(key, val, root);
    }

    private void insert(String key, int val, Node root) {
        if (key == null) {
            return;
        }

        //从根节点出发
        Node pre = root;
        for (int i = 0; i < key.length(); i++) {
            //判断当前字符是否已经存储过,存储过就跳过,否则新建
            int index = key.charAt(i) - 'a';
            
            //注意这里的空节点,不能采用Node tmp = pre.childs[index]的形式来判断,会出现空指针异常
            
            if (pre.childs[index] == null) {
                pre.childs[index] = new Node();
            }
            pre = pre.childs[index];
        }
        //添加完之后,标记置为true
        pre.isLeaf = true;
        pre.val = val;
    }

    public int sum(String prefix) {
        if (prefix == null) {
            return 0;
        }
        //遍历到prefix的最后一位字符所在的Node
        Node pre = root;
        for (int i = 0; i < prefix.length(); i++) {
            //找到当前字符所在的Node位置
            int index = prefix.charAt(i) - 'a';
            Node tmp = pre.childs[index];
            //如果不存在prefix这个前缀,返回0
            if (tmp == null) {
                return 0;
            }
            pre = tmp;
        }
        return sum(pre);
    }

    private int sum(Node node) {
        //base case
        if (node == null) {
            return 0;
        }
        //将当前节点值添加到sum
        int sum = node.val;
        //遍历当前节点的所有子节点
        for (Node child : node.childs) {
            //只进入不为空的子节点
            if (child != null) {
                sum += sum(child);
            }
        }
        return sum;
    }
}

作者:学就完事了

链接:juejin.cn/post/684490…