zoukankan      html  css  js  c++  java
  • 146. LRU Cache

    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.
    
    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

    键值对想到hashmap, 增删节点考虑链表, + 头尾节点, 因此要构造相应的类

    双向链表需要头尾节点

    The problem can be solved with a hashtable that keeps track of the keys and its values in the double linked list. One interesting property about double linked list is that the node can remove itself without other reference. In addition, it takes constant time to add and remove nodes from the head or tail.

    One particularity about the double linked list that I implemented is that I create a pseudo head and tail to mark the boundary, so that we don't need to check the NULL node during the update. This makes the code more concise and clean, and also it is good for the performance as well.

    public class LRUCache {
        private class Node{
            int key;
            int value;
            Node pre;
            Node next;
            public Node(int key, int value) {
                this.key = key;
                this.value = value;
                this.pre = null;
                this.next = null;
            }
        }
        private int capacity;
        private Node head = new Node(-1, -1);
        private Node tail = new Node(-1, -1);
        HashMap<Integer, Node> map = new HashMap<>();
        public LRUCache(int capacity) {
            this.capacity = capacity;
            head.next = tail;
            tail.pre = head;
        }
        
        public int get(int key) {
            if (!map.containsKey(key)) {
                return -1;
            }
            Node cur = map.get(key);
            cur.pre.next = cur.next;
            cur.next.pre = cur.pre;
            moveToTail(cur);
            return cur.value;
            
        }
        
        public void put(int key, int value) {
            if (get(key) != -1) {
                map.get(key).value = value;
                return;
            }
            Node cur = new Node(key, value);
            if (map.size() == capacity) {
                map.remove(head.next.key);
                head.next.next.pre = head;
                head.next = head.next.next;
               
            }
            map.put(key, cur);
            moveToTail(cur);
            
        }
        private void moveToTail(Node cur) {
            tail.pre.next = cur;
            cur.pre = tail.pre;
            tail.pre = cur;
            cur.next = tail;
        }
    }
    
    /**
     * 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);
     */
    
    public LinkedHashMap(int initialCapacity,
                         float loadFactor,
                         boolean accessOrder)
    Constructs an empty LinkedHashMap instance with the specified initial capacity, load factor and ordering mode.
    Parameters:
    initialCapacity - the initial capacity
    loadFactor - the load factor
    accessOrder - the ordering mode - true for access-order, false for insertion-order
    public class LRUCache {
            private LinkedHashMap<Integer, Integer> map;
            private final int CAPACITY;
            public LRUCache(int capacity) {
                CAPACITY = capacity;
                map = new LinkedHashMap<Integer, Integer>(capacity, 0.75f, true){
                    protected boolean removeEldestEntry(Map.Entry eldest) {
                        return size() > CAPACITY;
                    }
                };
            }
            public int get(int key) {
                return map.getOrDefault(key, -1);
            }
            public void set(int key, int value) {
                map.put(key, value);
            }
        }
    

      

     map.get(key).value = value;

    Wish : 第二轮电面, 中国大哥,LRU。 不让用dummy head tail。 处理corner case写出了bug

    public class LRUCache {
        private class Node{
            int key;
            int value;
            Node pre;
            Node next;
            public Node(int key, int value) {
                this.key = key;
                this.value = value;
                this.pre = null;
                this.next = null;
            }
        }
        private int capacity;
        private Node head = null;
        private Node tail = null;
        HashMap<Integer, Node> map = new HashMap<>();
        public LRUCache(int capacity) {
            this.capacity = capacity;
           
        }
         
        public int get(int key) {
            if (!map.containsKey(key)) {
                return -1;
            }
            Node cur = map.get(key);
            if (cur.key == head.key) {
                if (map.size() != 1) {
                    head = head.next;
                    head.pre = null; 
                    moveToTail(cur); 
                }
               
            } else {
                if (cur.key != tail.key) {
                  cur.pre.next = cur.next;
                cur.next.pre = cur.pre;
               moveToTail(cur);   
                }
               
            }
             
            return cur.value;
             
        }
         
        public void put(int key, int value) {
            if (get(key) != -1) {
                map.get(key).value = value;
                return;
            }
            Node cur = new Node(key, value);
            if (map.size() == capacity) {
                map.remove(head.key);
                if (map.size() == 0) {
                    head = null;
                    tail = null;
                } else {
                     head = head.next;
                    head.pre = null;
                }
               
               
                
            }
            if (head == null) {
                head = cur;
                tail = cur;
                
            } else {
                moveToTail(cur);
            }
            map.put(key, cur);
            
             
        }
        private void moveToTail(Node cur) {
            tail.next = cur;
            cur.pre = tail;
           tail = cur;
        }
    }
    /**
     * 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);
     */
    

      

     
  • 相关阅读:
    oracle 锁表查看与解锁
    oracle 监视索引是否使用
    oracle 查看数据库版本
    mybatis 中文做参数报错
    windows mysql绿色版配置
    maven使用本地jar包
    Java 使用Jedis连接Redis数据库(-)
    Linux 安装redis
    ELK之在CentOS7.5上使用rpm包安装配置ELK7版本
    Ubuntu-18.04更改安装源为国内源
  • 原文地址:https://www.cnblogs.com/apanda009/p/7242199.html
Copyright © 2011-2022 走看看