【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:
- get(key):如果链表中有key对应的node,返回该node的值,并把node移到链表头部(最近使用过);如果没有,返回-1;
- 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数据节点存放在二者之间。
分类:
leetcode刷题总结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了