zoukankan      html  css  js  c++  java
  • Java实现 LeetCode 432 全 O(1) 的数据结构

    432. 全 O(1) 的数据结构

    实现一个数据结构支持以下操作:

    Inc(key) - 插入一个新的值为 1 的 key。或者使一个存在的 key 增加一,保证 key 不为空字符串。
    Dec(key) - 如果这个 key 的值是 1,那么把他从数据结构中移除掉。否者使一个存在的 key 值减一。如果这个 key 不存在,这个函数不做任何事情。key 保证不为空字符串。
    GetMaxKey() - 返回 key 中值最大的任意一个。如果没有元素存在,返回一个空字符串""。
    GetMinKey() - 返回 key 中值最小的任意一个。如果没有元素存在,返回一个空字符串""。
    挑战:以 O(1) 的时间复杂度实现所有操作。

    PS:
    双链表+HashMap

    class AllOne {
    
        class Node{
            int value;
            String key;
            Node pre;
            Node next;
            public Node(String key, int value) {
                this.key = key;
                this.value = value;
            }
        }
        
        HashMap<String, Node> map = new HashMap<>();
        
        Node head;
        Node tail;
        /** Initialize your data structure here. */
        public AllOne() {
            head = new Node("", -1);
            tail = new Node("", -1);
            head.next = tail;
            tail.pre = head;
        }
        
        // 将src插入到des的前面
        public void insertPre(Node src, Node des) {
            Node temp = des.pre;
            temp.next = src;
            src.pre = temp;
            des.pre = src;
            src.next = des;
        }
        
        // 将src插入到des的后面
        public void insertNext(Node src, Node des) {
            Node temp = des.next;
            temp.pre = src;
            src.next = temp;
            des.next = src;
            src.pre = des;
        }
        
        /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
        public void inc(String key) {
            // 如果map中包含key,找到key对应的node
            if(map.containsKey(key)) {
                Node node = map.get(key);
                node.value ++;
                // 找到大于等于它的第一个Node,插入到其前面
                if(node.next != tail) {
                    Node temp = node.next;
                    while(temp!=tail && temp.value<node.value) {
                        temp = temp.next;
                    }
                    // 连接node断开处前面的和后面的节点
                    node.pre.next = node.next;
                    node.next.pre = node.pre;
                    // 将node插入到temp的前面
                    insertPre(node, temp);
                }
              
            } else {
                // 如果map中不包含key,则直接创建一个node插入到head的后面,同时将key记录到map中
                Node node = new Node(key, 1);
                map.put(key, node);
                insertNext(node, head);
            }
        }
        
        /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
        public void dec(String key) {
            // map中包含key,不包含的话不管了
            if(map.containsKey(key)) {
                Node node = map.get(key);
                // 如果key对应的node值为1,则从链表中移除节点,map中也移除该key
                if(node.value == 1) {
                  node.pre.next = node.next;
                  node.next.pre = node.pre;  
                  map.remove(key);
                } else {
                  // 如果key对应的node值不为1,则向前寻找到它前方的第一个小于它的节点temp,插入到temp后方
                  node.value --;
                  if(node.pre != head) {
                    Node temp = node.pre;
                    while(temp!=head && temp.value>node.value) {
                        temp = temp.pre;
                    }
                    // 连接断开处的
                    node.pre.next = node.next;
                    node.next.pre = node.pre;
                    // 插入到temp后方
                    insertNext(node, temp);
                    
                  }
                    
                }
                
            }
        }
        
        /** Returns one of the keys with maximal value. */
        public String getMaxKey() {
            return tail.pre.key;
        }
        
        /** Returns one of the keys with Minimal value. */
        public String getMinKey() {
            return head.next.key;
        }
    }
    
     
    
    /**
     * Your AllOne object will be instantiated and called as such:
     * AllOne obj = new AllOne();
     * obj.inc(key);
     * obj.dec(key);
     * String param_3 = obj.getMaxKey();
     * String param_4 = obj.getMinKey();
     */
    
  • 相关阅读:
    网络编程定时器一:使用升序链表
    木秀林网,网站专注于消息队列技术的研究
    Disruptor Ringbuffer
    Elasticsearch( 插件开发)
    Elasticsearch源码分析(一)启动流程 ModuleBuilder injector
    NativeScriptEngineService 被调用流程
    JAX-RS Resteasy
    gradle eclipse 配置
    maven repository 配置
    Eclipse中部署ES源码运行
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12946484.html
Copyright © 2011-2022 走看看