栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

D15 LeetCode 432.全O(1)的数据结构(困难)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

D15 LeetCode 432.全O(1)的数据结构(困难)

一、题目

class AllOne {

    public AllOne() {

    }
    
    public void inc(String key) {

    }
    
    public void dec(String key) {

    }
    
    public String getMaxKey() {

    }
    
    public String getMinKey() {

    }
}

 二、思路(自己)

这个题目我感觉并不难,就是设计一个数据结构和它的函数,但是其实有点难理解的是它的题意。比如输入代表什么意思,还有就是字符串key的计数是什么意思?这里我绕了好大的弯,getMaxKey返回任意一个计数最大的字符串?(挺打脸的,它要求时间复杂度为O(1)))我代码写完执行出错才发现原来我理解错意思了,其实它的计数指的是AllOne中该字符串的个数,我理解为该字符串的比较大小了。如下为我的错误代码:

class AllOne {
    List list=new ArrayList<>();


    public AllOne() {

    }

    public void inc(String key) {
        list.add(key);
    }

    public void dec(String key) {
        list.remove(key);
        if(list.size()==0) list.clear();
    }

    public String getMaxKey() {
        if(this.list.size()==0) return "";
        String s="";
        for (int i = 0; i 0){
                s=list.get(i);
            }
        }
        return s;
    }

    public String getMinKey() {
        if(this.list.size()==0) return "";
        String s=list.get(0);
        for (int i = 0; i s2.length()) return 1;
        if(s1.length() 

比较有意思的是居然还通过了10个测试用例懂题目意思了其实就不难了,因为之前也做过类似的题目。但是,我犯了个小错误,弄得我一直提交之后解答出错。

class AllOne {
 //   List list=new ArrayList<>();
    Map map=new HashMap<>();


    public AllOne() {

    }

    public void inc(String key) {
        if(this.map.containsKey(key))
            this.map.put(key,this.map.get(key)+1);
        else
            this.map.put(key,1);
    }

    public void dec(String key) {
        if(this.map.containsKey(key)){
            this.map.put(key,this.map.get(key)-1);
        if(this.map.get(key)==0) map.remove(key);
        }
    }
    Comparator> com=new Comparator>() {
        @Override
        public int compare(Map.Entry o1, Map.Entry o2) {
            return o1.getValue()-o2.getValue();
        }
    };

    public String getMaxKey() {
        if(this.map.size()==0) return "";
        //又是按照map的值取key,之前做过
        List> list=new ArrayList<>(this.map.entrySet());
        Collections.sort(list,com);
        return list.get(list.size()-1).getKey();
    }

    public String getMinKey() {
        if(this.map.size()==0) return "";
        List> list=new ArrayList<>(this.map.entrySet());
        Collections.sort(list,com);
        return list.get(0).getKey();
    }
}

最后还是未通过,为什么呢,时间复杂度高了

我记得我之前做过类似的题,是用set去重好像,但是具体怎么用我还是忘记了。。。我去翻翻以前的笔记。。。找不见了,估计那时候还没开始写博客

三、题解(官方)

题目要求O(1)的时间复杂度我看了评论区宫水三叶的答案,真厉害,是自己写一个哈希表来实现时间复杂度定义节点类,用来存储字符串出现的次数以下为代码和注释,挺好理解的

class AllOne{
    //定义节点类用来作为哈希表的数组部分
    class Node{
        int cnt;//字符串出现的次数
        Set set=new HashSet<>();//次数为cnt的字符串
        Node left,right;//链表前后元素
        Node(int _cnt){
            cnt=_cnt;
        }
    }

    Node hh,tt;
    //记录输入的节点,减少遍历来查找
    Map map=new HashMap<>();
    public AllOne(){
        //初始化双链表
        hh=new Node(-1000);tt=new Node(-1000);
        hh.right=tt; tt.left=hh;
    }

    void  clear(Node node){
        if(node.set.size()==0){
            //如果node中没有字符串了,那么就把它消掉
            node.left.right=node.right;
            node.right.left=node.left;
        }
    }

    public void inc(String key){
        //如果之前已经存储过现在输入的字符串
        if(map.containsKey(key)){
            //取出哈希表数组部分的节点
            Node node=map.get(key);
            //因为该字符串数量加一,所以不能待在哈希表这个数组部分
            node.set.remove(key);
            int cnt=node.cnt;
            Node next=null;
            if(node.right.cnt==cnt+1){
                //如果数量加一后为后面那个数组部分的数量,则将其放到下一个节点的位置
                next=node.right;
            }else {
                //没有对应数量的节点,且后面的那个节点一定大于加一,将节点插入到刚才所在节点后面
                next=new Node(cnt+1);
                next.right=node.right;
                next.left=node;
                node.right.left=next;
                node.right=next;
            }
            next.set.add(key);
            //记录加入节点和位置
            map.put(key,next);
            clear(node);
        }else {//如果之前没有存储过这个字符串,那么该字符串数量为1
            Node node=null;
            if(hh.right.cnt==1){
                node=hh.right;//之前存在数量为1的字符串
            }else {//没有数量为1的字符串,插入
                node=new Node(1);
                node.right=hh.right;
                node.left=hh;
                hh.right.left=node;
                hh.right=node;
            }
            node.set.add(key);//把字符串放入node中
            map.put(key,node);
        }
    }

    public void dec(String key){
        Node node=map.get(key);//找出key对应的节点位置
        node.set.remove(key);
        int cnt=node.cnt;
        if(cnt==1){
            map.remove(key);
        }else {
            Node prev=null;
            if(node.left.cnt==cnt-1){
                prev=node.left;
            }else {
                prev=new Node(cnt-1);
                prev.right=node;
                prev.left=node.left;
                node.left.right=prev;
                node.left=prev;
            }
            prev.set.add(key);
            map.put(key,prev);
        }
        clear(node);
    }
    
    public String getMaxKey(){
        Node node=tt.left;
        for(String str:node.set) return str;
        return "";
    }
    
    public String getMinKey(){
        Node node=hh.right;
        for(String str:node.set) return str;
        return "";
    }
}

继续加油!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/771229.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号