JAVA(2021-11-14)leetcode每日一题----键值映射

leetcode 专栏收录该内容
25 篇文章 0 订阅

 分析题目:要求的结构需要唯一的键值,即如果先后输入【apple,3】【apple,2】最后在求sum的时候需要把原来的3删掉,而符合这一属性的结构,应该就是前缀树和哈希表的结合了。

class TrieNode{

    public  int pass;
    public TrieNode[] nexts;
    public TrieNode() {
        pass = 0;
        nexts = new TrieNode[26];
    }
}

前缀树的结构,节点的属性有pass和nexts数组,节点和节点之间代表字符,即如果节点a到节点b的next【】数组不为null,即表示有值,pass代表经过这个节点的key有多少的val。


    public void insert(String key, int val) {
        int isInsert = map.getOrDefault(key,0);
        map.put(key,val);
        val = val - isInsert;      
        if(key==null){
            return;
        }
        TrieNode cur = root;
        cur.pass+=val;
        for(char c:key.toCharArray()){
            int index = c-'a';
            if(cur.nexts[index]==null){
                cur.nexts[index] = new TrieNode();
            }
            cur = cur.nexts[index];
            cur.pass+=val;
        }
    }

        因为要满足同时只有一个key在我的前缀树中,如果插入的key不是第一个,我就应该把原来key留下的痕迹删掉,这就有了前三句代码,如果之前没有重复的key,val的值不改变,如果有重复的值,val代表的是和原来的差距是多少,然后接下来就是弥补差距,此处可以动手模拟一下。

后边就是简单的前缀树逻辑了,但是要明白,本题中的前缀树,字符在树枝上,而不是节点上。

下面是完整代码

class MapSum {

    private TrieNode root;
    Map<String, Integer> map;

    public MapSum() {
        root = new TrieNode();
        map = new HashMap<>();
    }
    
    public void insert(String key, int val) {
        int isInsert = map.getOrDefault(key,0);
        map.put(key,val);
        val = val - isInsert;      
        if(key==null){
            return;
        }
        TrieNode cur = root;
        cur.pass+=val;
        for(char c:key.toCharArray()){
            int index = c-'a';
            if(cur.nexts[index]==null){
                cur.nexts[index] = new TrieNode();
            }
            cur = cur.nexts[index];
            cur.pass+=val;
        }
    }
    
    public int sum(String prefix) {
        if(prefix==null){
            return 0;
        }
        TrieNode cur = root;
        char[] words = prefix.toCharArray();
        for(char c:words){
            int index = c-'a';
            if(cur.nexts[index]==null){
                return 0;
            }
            cur =cur.nexts[index];
        }
        return cur.pass;
    }
}

class TrieNode{

    public  int pass;
    public TrieNode[] nexts;
    public TrieNode() {
        pass = 0;
        nexts = new TrieNode[26];
    }
}
/**
 * Your MapSum object will be instantiated and called as such:
 * MapSum obj = new MapSum();
 * obj.insert(key,val);
 * int param_2 = obj.sum(prefix);
 */

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

花园宝宝胡图图

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值