LeetCode100 LRU缓存思路讲解

思路

这题的关键是同时满足两个要求:

  • O(1) 查找 :所以要用 HashMap。
  • 维护最近使用顺序 :所以要用 双向链表。

只用 HashMap 可以 O(1) 找到 key,但不知道哪个是"最近最少使用"的;

只用链表可以维护顺序,但查找是 O(n)。

所以要把两者结合起来。

数据结构设计

维护一个 双向链表,链表头部表示最近使用的,尾部表示最久未使用的。

同时维护一个 HashMap<Integer, Node>,用来 O(1) 找到某个 key 对应的节点。

  • get(key):

    • 如果 key 不存在,返回 -1。
    • 如果存在,把对应节点移到链表头部,表示最近使用过,然后返回它的值。
  • put(key, value):

    • 如果 key 已存在,更新值,并把节点移到链表头部。
    • 如果 key 不存在:
      • 新建节点,插入链表头部,并放入 map。
      • 如果超过容量,就删除链表尾部节点,同时从 map 中移除。

class LRUCache {

class Node{

int key;

int value;

Node prev;

Node next;

public Node(int key,int value ){

this.key=key;

this.value=value;

}

}

private final int capacity;

private final Map<Integer,Node> map;

private final Node head;

private final Node tail;

public LRUCache(int capacity) {

this.capacity=capacity;

this.map=new HashMap<>();

head=new Node(0,0);

tail=new Node(0,0);

head.next=tail;

tail.prev=head;

}

public int get(int key) {

if(!map.containsKey(key))

return -1;

Node node=map.get(key);

movetohead(node);

return node.value;

}

public void put(int key, int value) {

if(map.containsKey(key)){

Node node=map.get(key);

node.value=value;

movetohead(node);

return;

}

Node node=new Node(key,value);

map.put(key,node);

addtohead(node);

if(map.size()>capacity){

Node lastnode=tail.prev;

removetail();

map.remove(lastnode.key);

return;

}

}

private void addtohead(Node node){

head.next.prev=node;

node.prev=head;

node.next=head.next;

head.next=node;

}

private void removenode(Node node){

node.prev.next=node.next;

node.next.prev=node.prev;

}

private void movetohead(Node node){

removenode(node);

addtohead(node);

}

private Node removetail(){

Node lastnode=tail.prev;

removenode(lastnode);

return lastnode;

}

}

/**

* Your LRUCache object will be instantiated and called as such:

* LRUCache obj = new LRUCache(capacity);

* int param_1 = obj.get(key);

* obj.put(key,value);

*/

相关推荐
liangbo74 分钟前
03-JDK 10/11 局部变量推断与 LTS:var 到底该怎么用
java
2401_8858850444 分钟前
国际语音C#接口怎么写?.NET环境下实现国际语音验证码批量下发
开发语言·c#·.net
Percep_gan1 小时前
调用天翼云的对象存储ZOS,很详细
java·1024程序员节
若亦_1 小时前
数据结构>>优先级队列(堆)
java·数据结构
程序猿乐锅1 小时前
【从0-1学习Python | 第七篇】Python 面向对象基础
开发语言·笔记·后端·python·学习·1024程序员节
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 查询圈子个人动态:查询我的动态需求分析
java·开发语言·交友
denlaku1 小时前
JDK 23 新特性详解
java
凯瑟琳.奥古斯特1 小时前
力扣1016高效解法:剪枝优化技巧
开发语言·c++·算法·leetcode·职场和发展
code2cat1 小时前
Java高级篇之Hibernate:让对象映射到表,理解持久化与事务
java·后端·hibernate·1024程序员节
骑着蜗牛撵大象3272 小时前
飞牛fnOS部署Damselfly:Compose编排、照片目录与7100固定访问
java·docker·rpc·dubbo·fnos·照片管理·damselfly