前缀树是什么

前缀树(Trie树),又称字典树、单词查找树。常用于文本词频统计,可以最大限度的减少字符串比对的频率。

大概的结构如下:

每个结点都维护着一个next结点数组(普通链表维护的是next结点),大概形式如下:

    class TrieNode {
        public int val;
        public TrieNode[]next = new TrieNode[26];
    }

除了next数组外,可能还有其它的成员变量,例如上面的val,可根据具体场景定义。

next的下标是字母与'a'的差值,

'a' - 'a' = 0

'b' - 'a' = 1

'c' - 'a' = 2

......

实战:LeetCode:677. 键值映射

题目:

实现一个 MapSum 类,支持两个方法,insert 和 sum:

MapSum() 初始化 MapSum 对象
void insert(String key, int val) 插入 key-val 键值对,字符串表示键 key ,整数表示值 val 。如果键 key 已经存在,那么原来的键值对将被替代成新的键值对。
int sum(string prefix) 返回所有以该前缀 prefix 开头的键 key 的值的总和。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/map-sum-pairs

实现方式:

class MapSum {
    
    class TrieNode {
        public int val;
        public TrieNode[]next = new TrieNode[26];
    }

    Map<String, Integer>map;
    TrieNode root;

    public MapSum() {
        map = new HashMap<>();
        root = new TrieNode();
    }
    
    public void insert(String key, int val) {
        int div = val - map.getOrDefault(key, 0);
        map.put(key, val);
        
        TrieNode node = root;
        for(int i = 0; i < key.length(); i++) {
            char c = key.charAt(i);
            if(node.next[c - 'a'] == null) {
                node.next[c - 'a'] = new TrieNode();
            }

            node = node.next[c - 'a'];
            node.val = div + node.val;
        }
    }
    
    public int sum(String prefix) {
        if(prefix == null) {
            return 0;
        }
        TrieNode p = root;
        for(int i = 0; i < prefix.length(); i++) {
            if(p == null) {
                break;
            }
            p = p.next[prefix.charAt(i) - 'a'];
        }

        return p == null ? 0 : p.val;
    }
}

/**
 * Your MapSum object will be instantiated and called as such:
 * MapSum obj = new MapSum();
 * obj.insert(key,val);
 * int param_2 = obj.sum(prefix);
 */

div用于存储字符替换所带来的差值,val用于存储符合前缀的单词总和,时间复杂度为O(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值