zoukankan      html  css  js  c++  java
  • [LeetCode]LRU Cache

    题目:实现一个LRU Cache

    算法:

    • 双向链表 + HashMap
    • get:若节点不存在,返回-1;否则返回节点value。并将节点调整到head
    • set(key, value):
      • 若key已经存在:更新value。并将节点调整到head;
      • 若key不存在:若cache容量足够。将节点压入链表头部;若cache容量不足。淘汰链表尾部节点。并将新节点压入链表头部


    import java.util.HashMap;
    
    
    public class LRUCache {
        /**
         * Structure
         * 
         * @author ouyangyewei
         */
        public class CacheNode {
            public int key;
            public int value;
            public CacheNode prev;
            public CacheNode next;
            
            public CacheNode() {
                // nothing
            }
            public CacheNode(int key, int value) {
                this.key = key;
                this.value = value;
                this.prev = null;
                this.next = null;
            }
        }
        
        private int capacity;
        private int currentCapacity;
        private CacheNode head;
        private CacheNode tail;
        private HashMap<Integer, CacheNode> hashNode;
        
        public LRUCache(int capacity) {
            this.capacity = capacity;
            this.currentCapacity = 0;
            this.head = null;
            this.tail = null;
            this.hashNode = new HashMap<Integer, CacheNode>();
        }
        
        public int get(int key) {
            CacheNode node = hashNode.get(key);
            if (null == node) {
                return -1;
            } else {
                moveToHead(node);
                return node.value;
            }
        }
        
        public void set(int key, int value) {
            if (null == hashNode.get(key)) {
                /** cacheNode is not exists! */
                CacheNode node = new CacheNode(key, value);
                if (currentCapacity < capacity) {
                    /** enough capacity for add a node */
                    addToHead(node);
                    ++currentCapacity;
                } else {
                    /** over the maximum capacity */
                    removeLeastUseNode();
                    addToHead(node);
                    currentCapacity = capacity;
                }
                
                hashNode.put(key, node);
            } else {
                /** cacheNode is already exists */
                CacheNode node = hashNode.get(key);
                node.value = value;
                moveToHead(node);
                hashNode.put(key, node);
            }
        }
        
        /**
         * Move a node to list's head
         * @param node
         */
        public void moveToHead(CacheNode node) {
            if (null != node.prev) {
                /** node locate behind the list's head */
                CacheNode front = node.prev;
                CacheNode behind = node.next;
                if (null == behind) {
                    /** node locate at the list's tail */
                    front.next = behind;
                    tail = front;
                } else {
                    front.next = behind;
                    behind.prev = front;
                }
                
                node.prev = null;
                node.next = head;
                head.prev = node;
                head = node;
            }
        }
        
        /**
         * Add a node to list's head.
         * @param node
         */
        public void addToHead(CacheNode node) {
            if (null == head) {
                /** list is empty */
                head = node;
                tail = node;
            } else {
                /** list is not empty */
                node.next = head;
                head.prev = node;
                head = node;
            }
        }
        
        /**
         * Remove the least use node, it means remove 
         * the list's tail node.
         */
        public void removeLeastUseNode() {
            if (null != tail.prev) {
                hashNode.remove(tail.key);
                tail = tail.prev;
                tail.next = null;
            } else {
                /** list has only one node */
                hashNode.remove(tail.key);
                head = null;
                tail = null;
            }
        }
        
    //    public static void main(String[] args) {
    //        LRUCache lruCache = new LRUCache(4);
    //        lruCache.set(1, 1);
    //        lruCache.set(0, 0);
    //        lruCache.get(1);
    //        lruCache.get(0);
    //        lruCache.set(2, 2);
    //        lruCache.set(4, 4);
    //        lruCache.get(1);
    //        lruCache.get(0);
    //        lruCache.get(0);
    //        lruCache.set(8, 8);
    //        lruCache.set(7, 7);
    //        lruCache.set(5, 5);
    //        lruCache.set(4, 4);
    //        lruCache.set(3, 3);
    //        lruCache.set(2, 2);
    //        lruCache.get(3);
    //        lruCache.get(4);
    //        LRUCache lruCache = new LRUCache(1);
    //        lruCache.set(2, 1);
    //        System.out.println(lruCache.get(2));
    //        lruCache.set(3, 2);
    //        System.out.println(lruCache.get(2));
    //        System.out.println(lruCache.get(3));
    //        LRUCache lruCache = new LRUCache(2);
    //        lruCache.set(2, 1);
    //        lruCache.set(1, 2);
    //        lruCache.set(2, 3);
    //        lruCache.set(4, 1);
    //        System.out.println(lruCache.get(1));
    //        System.out.println(lruCache.get(2));
    //    }
    }
    

  • 相关阅读:
    暑假D16 T3 密道(数位DP? 打表找规律)
    暑假D16 T2 无聊 (深搜)
    暑假D14 T3 cruise(SDOI2015 寻宝游戏)(虚树+set)
    Django url
    http协议
    host文件以及host的作用
    用socket写一个简单的服务器
    python中*args **kwargs
    javascript 判断对像是否相等
    html input标签详解
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7058013.html
Copyright © 2011-2022 走看看