zoukankan      html  css  js  c++  java
  • 【leetcode刷题笔记】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.


    题解:用双向链表实现一个LRU cache,这里自定义越靠近链表头的node,在越近的时间使用过。支持两个操作——get和set:

    1. get(key):如果链表中有key对应的node,返回该node的值,并把node移到链表头部(最近使用过);如果没有,返回-1;
    2. set(key,value):如果链表中已经有key对应的node,修改对应node的值为value(但不需要把这个node放在头结点处);如果链表中没有key对应的node,那么要新建node插入链表中,但此时要看链表是否还有空间。如果没有,就将尾部node(最少使用的node)删除,然后在头部插入新的node。

    为了提高查找效率,这里使用一个hashMap存放<key,node>键值对,这样就可以在O(1)的时间判断cache中是否存在对应的key。

    代码如下:

     1 public class LRUCache {
     2     private class Node{
     3         int value;
     4         int key;
     5         Node before;
     6         Node after;
     7         public Node(int key,int value){
     8             this.value = value;
     9             this.key = key;
    10             before = null;
    11             after = null;
    12         }
    13     }
    14     
    15     private int capacity;
    16     private HashMap<Integer, Node> map = new HashMap<Integer,Node>();
    17     private Node headNode = new Node(-1, -1);
    18     private Node tailNode = new Node(-1, -1);
    19     
    20     public LRUCache(int capacity) {
    21         this.capacity = capacity;
    22         headNode.after = tailNode;
    23         tailNode.before = headNode;
    24     }
    25     
    26     public void move_to_head(Node current){
    27         current.after = headNode.after;
    28         headNode.after = current;
    29         current.before = headNode;
    30         current.after.before = current;
    31     }
    32     public int get(int key) {
    33         //if we don't have this node
    34         if(!map.containsKey(key))
    35             return -1;
    36         
    37         //if we have this node, get it and move it to head
    38         Node current = map.get(key);
    39         current.before.after = current.after;
    40         current.after.before = current.before;
    41         move_to_head(current);
    42         
    43         return map.get(key).value;        
    44     }
    45     
    46     public void set(int key, int value) {
    47         //if we already have this node,just change its value
    48         if(get(key) != -1){
    49             map.get(key).value = value;
    50             return;
    51         }
    52         
    53         //if we indeed don't have this node, we first check capacity
    54         if(map.size() == capacity){
    55             map.remove(tailNode.before.key);
    56             tailNode.before.before.after = tailNode;
    57             tailNode.before = tailNode.before.before;
    58         }
    59         
    60         //now we are sure we have space for this new node,put it ahead of the list
    61         Node newNode = new Node(key, value);
    62         map.put(key, newNode);
    63         move_to_head(newNode);
    64     }
    65 }

    在实现的时候,还设置了两个node:head和tail,真正的cache数据节点存放在二者之间。

  • 相关阅读:
    OpenWrt编译系统(1)之make之前
    IoT设备WiFi配网及现状
    Linux系统时间、时区、夏令时杂谈
    串口通信概念整理
    socket编程进阶之路
    段错误
    gitlab将分支代码合并到master上
    dpkg 管理二进制包
    linux 命令关闭网络
    pwn之exp问题反馈和ASLR认知
  • 原文地址:https://www.cnblogs.com/sunshineatnoon/p/3854661.html
Copyright © 2011-2022 走看看