zoukankan      html  css  js  c++  java
  • 使用HashMap+双向链表实现LRU

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

    get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
    put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

    The cache is initialized with a positive capacity.

    Follow up:
    Could you do both operations in O(1) time complexity?

    Example:

    LRUCache cache = new LRUCache( 2 /* capacity */ );
    
    cache.put(1, 1);
    cache.put(2, 2);
    cache.get(1); // returns 1
    cache.put(3, 3); // evicts key 2
    cache.get(2); // returns -1 (not found)
    cache.put(4, 4); // evicts key 1
    cache.get(1); // returns -1 (not found)
    cache.get(3); // returns 3
    cache.get(4); // returns 4

    思路:

    可以直接使用LinkHashMap实现LRU。

    LinkedHashMap实现原理基于HashMap+双向链表,这里自己实现一遍。


    题解:

    import java.util.HashMap;
    
    class LRUCache {
    
        class Node {
            int key;
            int value;
            Node prev;
            Node next;
        }
    
        /**
         * 向双向链表加入新节点
         * 加入到表头
         */
        private void addNode(Node node) {
            node.prev = head;
            node.next = head.next;
            head.next.prev = node;
            head.next = node;
        }
    
        /**
         * 删除节点
         */
        private void removeNode(Node node) {
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }
    
        /**
         * 删除表尾节点
         */
        private Node popTail() {
            Node node = tail.prev;
            removeNode(node);
            return node;
        }
    
        /**
         * 移动到表头
         * 1.删除原节点
         * 2.在表头插入原节点
         */
        private void moveToHead(Node node) {
            removeNode(node);
            addNode(node);
        }
    
        private int capacity;
        private int size;
        private HashMap<Integer, Node> cache;
        private Node head;
        private Node tail;
    
        public LRUCache(int capacity) {
            this.capacity = capacity;
            this.size = 0;
            cache = new HashMap<>();
            head = new Node();
            tail = new Node();
            head.next = tail;
            tail.prev = head;
        }
    
        /**
         * get()操作
         * 如果key对应的value不存在,返回-1
         * 如果存在,则获取值,并将节点移动到表头
         */
        public int get(int key) {
            Node node = cache.get(key);
            if (node == null) return -1;
            moveToHead(node);
            return node.value;
        }
    
        /**
         * put()操作
         * 如果key不存在,则新建节点,将节点加入cache map,放置到表头,size+1
         * 如果size>capacity,要去除表尾节点,并从cache中删除,size-1
         * 如果key存在,将该节点的值更新,并移动到表头
         */
        public void put(int key, int value) {
            Node node = cache.get(key);
            if (node == null) {
                node = new Node();
                node.key = key;
                node.value = value;
                cache.put(key, node);
                addNode(node);
                size++;
                if (size > capacity) {
                    Node del = popTail();
                    cache.remove(del.key);
                    size--;
                }
            } else {
                node.value = value;
                moveToHead(node);
            }
        }
    
        public static void main(String[] args) {
            LRUCache lruCache = new LRUCache(2);
            lruCache.put(1, 1);
            lruCache.put(2, 2);
            lruCache.get(1);
            lruCache.put(3, 3);
            lruCache.get(2);
            lruCache.put(4, 4);
            lruCache.get(1);
            lruCache.get(3);
            lruCache.get(4);
        }
    }
    
    /**
     * Your LRUCache object will be instantiated and called as such:
     * LRUCache obj = new LRUCache(capacity);
     * int param_1 = obj.get(key);
     * obj.put(key,value);
     */
  • 相关阅读:
    自动补全命令插件的安装(centos)
    vim tab设置为4个空格
    CentOS系统将UTC时间修改为CST时间
    Zabbix报错 zabbix:cannot convert value to numeric type解决
    php-fpm平滑重启开启关闭
    虚拟机启动network服务失败,Job for network.service failed because the control process exited with error code问题
    Tomcat中设置站点子目录的方法
    WordPress添加背景音乐plus教程
    WordPress使用必应每日一图作登录页面背景
    WordPress自定义美化
  • 原文地址:https://www.cnblogs.com/yfzhou/p/11246472.html
Copyright © 2011-2022 走看看