zoukankan      html  css  js  c++  java
  • LRU Cache leetcode java

    题目:

    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.

    题解:

    这道题是一个数据结构设计题,在leetcode里面就这么一道,还是挺经典的一道题,可以好好看看。

    这道题要求设计实现LRU cache的数据结构,实现set和get功能。学习过操作系统的都应该知道,cache作为缓存可以帮助快速存取数据,但是确定是容量较小。这道题要求实现的cache类型是LRU,LRU的基本思想就是“最近用到的数据被重用的概率比较早用到的大的多”,是一种更加高效的cache类型。

    解决这道题的方法是:双向链表+HashMap

    “为了能够快速删除最久没有访问的数据项和插入最新的数据项,我们将双向链表连接Cache中的数据项,并且保证链表维持数据项从最近访问到最旧访问的顺序 每次数据项被查询到时,都将此数据项移动到链表头部(O(1)的时间复杂度)。这样,在进行过多次查找操作后,最近被使用过的内容就向链表的头移动,而没 有被使用的内容就向链表的后面移动。当需要替换时,链表最后的位置就是最近最少被使用的数据项,我们只需要将最新的数据项放在链表头部,当Cache满 时,淘汰链表最后的位置就是了。

     “注: 对于双向链表的使用,基于两个考虑。

                首先是Cache中块的命中可能是随机的,和Load进来的顺序无关。

             其次,双向链表插入、删除很快,可以灵活的调整相互间的次序,时间复杂度为O(1)。”

    解决了LRU的特性,现在考虑下算法的时间复杂度。为了能减少整个数据结构的时间复杂度,就要减少查找的时间复杂度,所以这里利用HashMap来做,这样时间苏咋读就是O(1)。

     所以对于本题来说:

    get(key): 如果cache中不存在要get的值,返回-1;如果cache中存在要找的值,返回其值并将其在原链表中删除,然后将其作为头结点。

    set(key,value):当要set的key值已经存在,就更新其value, 将其在原链表中删除,然后将其作为头结点;当药set的key值不存在,就新建一个node,如果当前len<capacity,就将其加入hashmap中,并将其作为头结点,更新len长度,否则,删除链表最后一个node,再将其放入hashmap并作为头结点,但len不更新。

    原则就是:对链表有访问,就要更新链表顺序。

    代码如下:

     1     private HashMap<Integer, DoubleLinkedListNode> map 
     2         = new HashMap<Integer, DoubleLinkedListNode>();
     3     private DoubleLinkedListNode head;
     4     private DoubleLinkedListNode end;
     5     private int capacity;
     6     private int len;
     7  
     8     public LRUCache(int capacity) {
     9         this.capacity = capacity;
    10         len = 0;
    11     }
    12  
    13     public int get(int key) {
    14         if (map.containsKey(key)) {
    15             DoubleLinkedListNode latest = map.get(key);
    16             removeNode(latest);
    17             setHead(latest);
    18             return latest.val;
    19         } else {
    20             return -1;
    21         }
    22     }
    23  
    24     public void removeNode(DoubleLinkedListNode node) {
    25         DoubleLinkedListNode cur = node;
    26         DoubleLinkedListNode pre = cur.pre;
    27         DoubleLinkedListNode post = cur.next;
    28  
    29         if (pre != null) {
    30             pre.next = post;
    31         } else {
    32             head = post;
    33         }
    34  
    35         if (post != null) {
    36             post.pre = pre;
    37         } else {
    38             end = pre;
    39         }
    40     }
    41  
    42     public void setHead(DoubleLinkedListNode node) {
    43         node.next = head;
    44         node.pre = null;
    45         if (head != null) {
    46             head.pre = node;
    47         }
    48  
    49         head = node;
    50         if (end == null) {
    51             end = node;
    52         }
    53     }
    54  
    55     public void set(int key, int value) {
    56         if (map.containsKey(key)) {
    57             DoubleLinkedListNode oldNode = map.get(key);
    58             oldNode.val = value;
    59             removeNode(oldNode);
    60             setHead(oldNode);
    61         } else {
    62             DoubleLinkedListNode newNode = 
    63                 new DoubleLinkedListNode(key, value);
    64             if (len < capacity) {
    65                 setHead(newNode);
    66                 map.put(key, newNode);
    67                 len++;
    68             } else {
    69                 map.remove(end.key);
    70                 end = end.pre;
    71                 if (end != null) {
    72                     end.next = null;
    73                 }
    74  
    75                 setHead(newNode);
    76                 map.put(key, newNode);
    77             }
    78         }
    79     }
    80 }
    81  
    82 class DoubleLinkedListNode {
    83     public int val;
    84     public int key;
    85     public DoubleLinkedListNode pre;
    86     public DoubleLinkedListNode next;
    87  
    88     public DoubleLinkedListNode(int key, int value) {
    89         val = value;
    90         this.key = key;
    91     }

     Reference:

    1. http://blog.csdn.net/hexinuaa/article/details/6630384 (引号中字引自此处)
    2. http://www.cnblogs.com/feiling/p/3426967.html
    3. http://www.programcreek.com/2013/03/leetcode-lru-cache-java/ (代码参考)

     

  • 相关阅读:
    hdu 1017 A Mathematical Curiosity 解题报告
    hdu 2069 Coin Change 解题报告
    hut 1574 组合问题 解题报告
    hdu 2111 Saving HDU 解题报
    hut 1054 Jesse's Code 解题报告
    hdu1131 Count the Trees解题报告
    hdu 2159 FATE 解题报告
    hdu 1879 继续畅通工程 解题报告
    oracle的系统和对象权限
    oracle 自定义函数 返回一个表类型
  • 原文地址:https://www.cnblogs.com/springfor/p/3869393.html
Copyright © 2011-2022 走看看