题目
分析
前缀树的创建模板,可以参考我之前写的两篇文章。
前缀树+dfs
class MapSum {
// 先建立一个内部类用以实现前缀树节点
class TreeNode{
// 前缀树有两个属性:
// 1.分支节点数组
// 2.终点标志位
// 此处根据题意附加一个额外属性:val
private TreeNode[] links;
private boolean isEnd;
private int val;
public TreeNode(){
links=new TreeNode[26];
isEnd=false;
val=0;
}
}
private TreeNode root;
/** Initialize your data structure here. */
public MapSum() {
root=new TreeNode();// 创建前缀树根节点
}
public void insert(String key, int val) {
// 前缀树插入操作
TreeNode cur=root;
for (int i=0; i<key.length(); i++){
if (cur.links[key.charAt(i)-'a']==null){
cur.links[key.charAt(i)-'a']=new TreeNode();
}
cur=cur.links[key.charAt(i)-'a'];
}
cur.isEnd=true;
cur.val=val;// 在最后一个节点处设置val
}
public int sum(String prefix) {
// sum的求和相当于是以前缀的最后一个节点作为根节点,查找树中的所有节点。
int res=0;
TreeNode cur=root;
// 先走前缀,然后继续搜索树中的非空节点。
for (int i=0; i<prefix.length(); i++){
if (cur.links[prefix.charAt(i)-'a']==null){
return res;
}
cur=cur.links[prefix.charAt(i)-'a'];
}
// 当走到这里时cur总不为空
res+=sumHelper(cur);
return res;
}
private int sumHelper(TreeNode root){
// 递归调用求和辅助函数,这里可以认为是dfs递归调用
// 我们这里不需要设置递归终止条件,因为我们的root节点总是不为空
// 只有root节点的links数组可能为空,为空则for循环内部的if不执行,res不变,最终返回0
int res=0;
TreeNode pointer=root;
if (pointer.isEnd) res+=pointer.val;
for (int i=0; i<26; i++){
// 检查根节点的26个分支,如果一个分支可以往下走就沿着该分支走下去
if (pointer.links[i]!=null) res+=sumHelper(pointer.links[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);
*/
字典树
class MapSum {
// 创建字典树节点类
private class Node{
public int value;
public HashMap<Character, Node> next;
public Node(int value)
{
this.value = value;
this.next = new HashMap<>();
}
public Node(){
this(0);
}
}
private Node root;
/** Initialize your data structure here. */
public MapSum() {
root = new Node();
}
public void insert(String key, int val) {
Node curr = root;
for(int i = 0; i < key.length(); i++)
{
char c = key.charAt(i);
if(curr.next.get(c) == null)
curr.next.put(c, new Node());
curr = curr.next.get(c);
}
curr.value = val;
}
public int sum(String prefix) {
Node curr = root;
for(int i = 0; i < prefix.length(); i++)
{
char c = prefix.charAt(i);
if(curr.next.get(c) == null)
return 0;
curr = curr.next.get(c);
}
return sum(curr);
}
private int sum(Node node)
{
int res = node.value;
for(char c : node.next.keySet())
res += sum(node.next.get(c));
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);
*/