前言
前缀树同系列的题目,可以用前缀树的思路来存储,只需要基于之前的前缀树实现改造。原题目要求如下:
实现一个 MapSum 类里的两个方法,insert 和 sum。对于方法 insert,你将得到一对(字符串,整数)的键值对。字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。
对于方法 sum,你将得到一个表示前缀的字符串,你需要返回所有以该前缀开头的键的值的总和。
示例 1:
输入: insert("apple", 3), 输出: Null
输入: sum("ap"), 输出: 3
输入: insert("app", 2), 输出: Null
输入: sum("ap"), 输出: 5
实现思路
- 参考前缀树实现的思路,把节点中的boolean变量改为键值对的值
- sum方法的时候首先要找到匹配前缀的节点,然后用层序遍历(广度优先)方式去遍历这个节点的子树。遍历的时候使用递归进行遍历。
实例代码
public class MapSum {
/**
* key的前缀字符
*/
char keyPrefix;
/**
* 子节点
*/
MapSum[] children;
/**
* 存储的值,不为0则为终止节点
*/
int value;
/** Initialize your data structure here. */
public MapSum() {
children=new MapSum[26];
value=0;
}
/**
* 字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。
* @param key 键
* @param val 值
*/
public void insert(String key, int val) {
if(key!=null){
//分解成字符数组
char[] charArr=key.toCharArray();
//模拟指针操作,记录当前访问到的树的节点
MapSum currentNode=this;
for(int i=0;i<charArr.length;i++){
char currentChar=charArr[i];
//根据字符获取对应的子节点
MapSum node=currentNode.children[currentChar-97];
if(node!=null && node.keyPrefix==currentChar){//判断节点是否存在
currentNode=node;
}else{//不存在则创建一个新的叶子节点,并指向当前的叶子节点
node=new MapSum();
node.keyPrefix=currentChar;
currentNode.children[currentChar-97]=node;
currentNode=node;
}
}
//存储值
currentNode.value=val;
}else{
this.value=val;
}
}
/**
* 根据表示前缀的字符串,返回所有以该前缀开头的键的值的总和。
* @param prefix 前缀
* @return
*/
public int sum(String prefix) {
int result=0;
//前缀是否匹配
boolean match=true;
if(prefix!=null && !prefix.trim().equals("")){
char[] prefixChar=prefix.toCharArray();
MapSum currentNode=this;
for(int i=0;i<prefixChar.length;i++){
char currentChar=prefixChar[i];
MapSum node=currentNode.children[currentChar-97];
if(node!=null && node.keyPrefix==currentChar){//判断节点是否存在
currentNode=node;
}else{
match=false;
break;
}
}
if(match){//前缀匹配后开始检索这个匹配节点后续的子树
result=sumByFloor(currentNode);
}
}
return result;
}
/**
* 层序遍历(广度优先)方式访问树
* @param mapSum
* @return
*/
private int sumByFloor(MapSum mapSum){
int result=0;
if(mapSum==null){
return 0;
}else{
result+=mapSum.value;
MapSum[] mapSums=mapSum.children;
for(MapSum sum:mapSums){
if(sum!=null){
result+=sumByFloor(sum);
}else{
result+=sumByFloor(sum);
}
}
}
return result;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。