实现一个 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;
}
}
作者:学就完事了