首页 > 编程语言 >#yyds干货盘点# LeetCode程序员面试金典:全 O(1) 的数据结构

#yyds干货盘点# LeetCode程序员面试金典:全 O(1) 的数据结构

时间:2023-09-24 18:01:35浏览次数:41  
标签:Node yyds cur 金典 next key nodes root LeetCode

1.简述:

请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。

实现 AllOne 类:

AllOne() 初始化数据结构的对象。

inc(String key) 字符串 key 的计数增加 1 。如果数据结构中尚不存在 key ,那么插入计数为 1 的 key 。

dec(String key) 字符串 key 的计数减少 1 。如果 key 的计数在减少后为 0 ,那么需要将这个 key 从数据结构中删除。测试用例保证:在减少计数前,key 存在于数据结构中。

getMaxKey() 返回任意一个计数最大的字符串。如果没有元素存在,返回一个空字符串 "" 。

getMinKey() 返回任意一个计数最小的字符串。如果没有元素存在,返回一个空字符串 "" 。

注意:每个函数都应当满足 O(1) 平均时间复杂度。

 

示例:

输入
["AllOne", "inc", "inc", "getMaxKey", "getMinKey", "inc", "getMaxKey", "getMinKey"]
[[], ["hello"], ["hello"], [], [], ["leet"], [], []]
输出
[null, null, null, "hello", "hello", null, "hello", "leet"]

2.代码实现:

class AllOne {
    Node root;
    Map<String, Node> nodes;

    public AllOne() {
        root = new Node();
        root.prev = root;
        root.next = root;  // 初始化链表哨兵,下面判断节点的 next 若为 root,则表示 next 为空(prev 同理)
        nodes = new HashMap<String, Node>();
    }
    
    public void inc(String key) {
        if (nodes.containsKey(key)) {
            Node cur = nodes.get(key);
            Node nxt = cur.next;
            if (nxt == root || nxt.count > cur.count + 1) {
                nodes.put(key, cur.insert(new Node(key, cur.count + 1)));
            } else {
                nxt.keys.add(key);
                nodes.put(key, nxt);
            }
            cur.keys.remove(key);
            if (cur.keys.isEmpty()) {
                cur.remove();
            }
        } else {  // key 不在链表中
            if (root.next == root || root.next.count > 1) {
                nodes.put(key, root.insert(new Node(key, 1)));
            } else {
                root.next.keys.add(key);
                nodes.put(key, root.next);
            }
        }
    }
    
    public void dec(String key) {
        Node cur = nodes.get(key);
        if (cur.count == 1) {  // key 仅出现一次,将其移出 nodes
            nodes.remove(key);
        } else {
            Node pre = cur.prev;
            if (pre == root || pre.count < cur.count - 1) {
                nodes.put(key, cur.prev.insert(new Node(key, cur.count - 1)));
            } else {
                pre.keys.add(key);
                nodes.put(key, pre);
            }
        }
        cur.keys.remove(key);
        if (cur.keys.isEmpty()) {
            cur.remove();
        }
    }
    
    public String getMaxKey() {
        return root.prev != null ? root.prev.keys.iterator().next() : "";
    }
    
    public String getMinKey() {
        return root.next != null ? root.next.keys.iterator().next() : "";
    }
}

class Node {
    Node prev;
    Node next;
    Set<String> keys;
    int count;

    public Node() {
        this("", 0);
    }

    public Node(String key, int count) {
        this.count = count;
        keys = new HashSet<String>();
        keys.add(key);
    }

    public Node insert(Node node) {  // 在 this 后插入 node
        node.prev = this;
        node.next = this.next;
        node.prev.next = node;
        node.next.prev = node;
        return node;
    }

    public void remove() {
        this.prev.next = this.next;
        this.next.prev = this.prev;
    }
}

标签:Node,yyds,cur,金典,next,key,nodes,root,LeetCode
From: https://blog.51cto.com/u_15488507/7587231

相关文章

  • 算法训练day18 LeetCode 513
    算法训练day18LeetCode513.112.106513.找树左下角的值题目513.找树左下角的值-力扣(LeetCode)题解代码随想录(programmercarl.com)递归方式单独数据存储最大深度,和此深度的结点值递归后要注意回溯classSolution{public:intmaxDepth=INT_MIN;......
  • Leetcode刷题21.合并两个有序链表
    将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。  示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例2:输入:l1=[],l2=[]输出:[]示例3:输入:l1=[],l2=[0]输出:[0] 提示:两个链表的节点数目......
  • 算法训练day8 LeetCode 344
    算法训练day8:LeetCode344.541.151.剑指offer05.58.344.反转字符串题目344.反转字符串-力扣(LeetCode)题解代码随想录(programmercarl.com)classSolution{public:voidreverseString(vector<char>&s){for(inti=0,j=s.size()-1;i......
  • 算法训练day17 LeetCode 110
    算法训练day17LeetCode110.257.404110平衡二叉树题目110.平衡二叉树-力扣(LeetCode)题解代码随想录(programmercarl.com)当子树已经不平衡,直接返回-1.平衡则返回子数高度进行更高树间的高度比较classSolution{public:intgetHeight(TreeNode*node)......
  • 【LeetCode】2591. 将钱分给最多的儿童
    描述给你一个整数money,表示你总共有的钱数(单位为美元)和另一个整数children,表示你要将钱分配给多少个儿童。你需要按照如下规则分配:所有的钱都必须被分配。每个儿童至少获得1美元。没有人获得4美元。请你按照上述规则分配金钱,并返回最多有多少个儿童获得恰好8......
  • # yyds干货盘点 # ChatGPT 实用小案例分享——使用Python重命名附件和统计发票合计金
    大家好,我是皮皮。一、前言前几天在【志军】的星球看到了一个有意思的ChatGPT分享,正好喝Python相关的,一起来看看吧。ChatGPT实用小案例分享。如果你在高德或者滴滴上申请过开票,应该知道它们会给我们发一封邮件,发票和行程单都会放在附件中。由于高德是聚合平台,背后有很多网约车平台,......
  • LeetCode3题学透链表初始化、查找、插入删除、逆置操作
    1.题目要求LeetCode203移除链表指定元素LeetCode707设计链表LeetCode206反转链表  这三个题目包含了链表的初始化、插入头尾结点、插入删除第n个结点,删除指定内容的结点、链表的逆置等,下面我将一一讲解并展示源代码。2.具体操作2.1LeetCode中链表的初始化  我下面所讲......
  • [leetcode] 10. 正则表达式匹配
    10.正则表达式匹配给你一个字符串s和一个字符规律p,请你来实现一个支持'.'和'*'的正则表达式匹配。'.'匹配任意单个字符'*'匹配零个或多个前面的那一个元素所谓匹配,是要涵盖整个字符串s的,而不是部分字符串。示例1:输入:s="aa",p="a"输出:false解释:"a"无......
  • #yyds干货盘点#Koa-router 优先级问题
    问题描述在使用Koa-router作为路由遇到了一个优先级问题.如下代码//routerPage.jsfileconstrouter=require("koa-router")router.get("/test",ctx=>{ctx.body="test"})router.get("/router/test",ctx=>{ctx.body="routertest......
  • 【LeetCode】收集树中金币
    链接题目给你一个n个节点的无向无根树,节点编号从0到n-1。给你整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi之间有一条边。再给你一个长度为n的数组coins,其中coins[i]可能为0也可能为1,1表示节点i处有......