【LeetCode】677.键值映射(前缀树,java实现)

题目

地址

image-20200628201136613

分析

前缀树的创建模板,可以参考我之前写的两篇文章。

前缀树详解

【LeetCode】208.实现前缀树

前缀树+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);
 */
原文地址:https://www.cnblogs.com/hzcya1995/p/13308011.html