• LRU Cache


    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.

    Ref: http://www.cnblogs.com/feiling/p/3426967.html

    [解题思路]

    LRU是Least Recently Used 的缩写,翻译过来就是“最不常使用”,也就是说,LRU缓存把最不常使用的数据移除,让给最新读取的数据。大多数情况下,最常读取的,也是读取次数最多的,所以,利用LRU缓存,我们能够提高系统的performance. LRU cache是非常频繁出现的一道面试题,一般来讲,当我们问到这道题时,面试官往往想得到的答案是利用 doubly linked list + hashtable 实现 LRU Cache, 那么我们现在就来讲一讲如何利用doubly linked list + hashtable实现LRU Cache的。

    这里为什么使用Doubly linkd list 而不使用 Linked list的原因是:

    当访问一个节点后,我们需要将他从原来的list中删除,然后将它插入到头节点处,删除过程中需要将其前后节点连接起来,单链表做不到。

    查询:

    • 根据键值查询hashmap,若命中,则返回节点,否则返回null。
    • 从双向链表中删除命中的节点,将其重新插入到表头。
    • 所有操作的复杂度均为O(1)。

    插入:

    • 将新的节点关联到Hashmap
    • 如果Cache满了,删除双向链表的尾节点,同时删除Hashmap对应的记录
    • 将新的节点插入到双向链表中头部

    更新:

    • 和查询相似

    删除:

    • 从双向链表和Hashmap中同时删除对应的记录。
    •  1 public class LRUCache {
       2     private DoubleLinkNode first;
       3     private DoubleLinkNode last;
       4     private int capacity;
       5     private int currentSize;
       6     private HashMap<Integer, DoubleLinkNode> nodesMap;
       7     
       8     
       9     public LRUCache(int capacity){
      10         this.capacity = capacity;
      11         currentSize = 0;
      12         nodesMap = new HashMap<Integer, DoubleLinkNode>();
      13         
      14     }
      15     
      16     public int get(int key){
      17         DoubleLinkNode node = nodesMap.get(key);
      18         if(node != null){
      19             moveToHead(node);
      20             return node.value;
      21         }else{
      22             return -1;
      23         }
      24     }
      25     
      26     public void set(int key, int value){
      27         DoubleLinkNode node = nodesMap.get(key);
      28         if(node == null){
      29             if(currentSize >= capacity){
      30                 nodesMap.remove(last.key);
      31                 removeLast();
      32             }else{
      33                 currentSize++;
      34             }
      35             node = new DoubleLinkNode();
      36         }
      37         
      38         if(currentSize == 1){
      39             first = node;
      40             last = node;
      41         }
      42         
      43         node.key = key;
      44         node.value = value;
      45         moveToHead(node);
      46         nodesMap.put(key,node);
      47     }
      48     
      49     private void moveToHead(DoubleLinkNode node){
      50             if(node == first)
      51                 return;
      52             
      53             if(last == node){
      54                 last = node.front;
      55             }
      56              // delete current node from doubly linked list
      57             if(node.front != null){
      58                 node.front.back = node .back;
      59             }
      60             
      61             if(node.back != null){
      62                 node.back.front = node.front;
      63             }
      64             
      65             if(first != null){
      66                 node.back = first;
      67                 first.front = node;
      68             }
      69             
      70             first = node;
      71             node.front = null;
      72     }
      73     
      74     private void removeLast(){
      75         if(last != null){
      76             if(last.front != null){
      77                 last.front.back = null;
      78             }else{
      79                 first = null;
      80             }
      81             last = last.front;
      82         }
      83     }   
      84 }
      85 
      86 class DoubleLinkNode{
      87     DoubleLinkNode front;
      88     DoubleLinkNode back;
      89     int key;
      90     int value;
      91 }
  • 相关阅读:
    【Nginx】跨域配置
    【Python】【Chart】图标绘制/地图生成
    【Python】操作压缩文件
    【VSCode】koroFileHeader插件自动添加文件及函数注释
    【性能】web页面性能之lighthouse使用
    【VSCode】格式化后换行
    【Python】MD5
    【IDEA】自定义/自动生成/注释/新增文件自动生成注释/自动生成方法注释
    【Java】文件下载/下载Excel/下载文件到本地
    【杂项】英语学习
  • 原文地址:https://www.cnblogs.com/RazerLu/p/3555330.html
Copyright © 2020-2023  润新知