LRU Cache

来源:互联网 发布:怎么退出windows账户 编辑:程序博客网 时间:2024/06/03 16:13

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

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(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.

思路:这里需要自己手动建立一个双向链表,然后加上HashMap的协助从而达到O(1)时间的定位,双向链表能帮助我们达到删除节点,插入节点O(1)时间复杂度。具体的实现并不是很复杂。

算法:http://www.hawstein.com/posts/lru-cache-impl.html

核心:当我们通过键值来访问类型为T的数据时,调用Get函数。如果键值为key的数据已经在 Cache中,那就返回该数据,同时将存储该数据的结点移到双向链表头部。 如果我们查询的数据不在Cache中,我们就可以通过Put接口将数据插入双向链表中。 如果此时的Cache还没满,那么我们将新结点插入到链表头部, 同时用哈希表保存结点的键值及结点地址对。如果Cache已经满了, 我们就将链表中的最后一个结点(注意不是尾结点)的内容替换为新内容, 然后移动到头部,更新哈希表。

注意: head, end的处理。head , end 是标示,其可以是node,也可以存储值。head.pre, head.next, end.pre, end.next都得注意更新。

public class LRUCache {    private class DoubleLinkedList{        int key;        int val;        DoubleLinkedList pre;        DoubleLinkedList post;        public DoubleLinkedList(int key, int val){            this.key = key;            this.val = val;        }    }        private int capacity = 0;    private int count = 0;    private DoubleLinkedList head = null;    private DoubleLinkedList end = null;    HashMap<Integer, DoubleLinkedList> hashmap;    public LRUCache(int capacity) {        this.capacity = capacity;        hashmap = new HashMap<Integer, DoubleLinkedList>();    }        private void removeNode(DoubleLinkedList node){        DoubleLinkedList prenode = node.pre;        DoubleLinkedList postnode = node.post;                if(prenode == null){            head = postnode;        } else { // prenode != null;            prenode.post = postnode;        }                if(postnode == null){            end = prenode;        } else {            postnode.pre = prenode;        }    }        private void setToHead(DoubleLinkedList node){        if(head == null){            head = node;        } else { // head != null;            head.pre = node;            node.post = head;            node.pre = null;            head = node;        }                if(end == null){            end = node;        }     }        public int get(int key) {        if(!hashmap.containsKey(key)){            return -1;        } else {            DoubleLinkedList node = hashmap.get(key);            removeNode(node);            setToHead(node);            return node.val;        }    }        public void set(int key, int value) {       if(hashmap.containsKey(key)){           DoubleLinkedList node = hashmap.get(key);           node.val = value;           removeNode(node);           setToHead(node);       } else { // don't contains;           if(count<this.capacity){               DoubleLinkedList node = new DoubleLinkedList(key, value);               setToHead(node);               hashmap.put(key, node);               count++;           } else { // count >=capacity;               hashmap.remove(end.key);               removeNode(end);               DoubleLinkedList node = new DoubleLinkedList(key, value);               setToHead(node);               hashmap.put(key, node);           }       }    }}


0 0
原创粉丝点击