HashMap+双向链表实现LRU算法
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache
类:
LRUCache(int capacity)
以 正整数 作为容量capacity
初始化 LRU 缓存int get(int key)
如果关键字key
存在于缓存中,则返回关键字的值,否则返回-1
。void put(int key, int value)
如果关键字key
已经存在,则变更其数据值value
;如果不存在,则向缓存中插入该组key-value
。如果插入操作导致关键字数量超过capacity
,则应该 逐出 最久未使用的关键字。
函数 get
和 put
必须以 O(1)
的平均时间复杂度运行。
class LRUCache { // LRU缓存 最近最少使用---思路:用双链表来模拟,HashMap来 int capacity; //容量 DoubleList cache; HashMap<Integer,Node> map; //初始化 public LRUCache(int capacity) { this.capacity = capacity; cache = new DoubleList(); map = new HashMap<>(); } //如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 public int get(int key) { if(map.containsKey(key)){ //如果存在,调整顺序 Node tempNode = map.get(key); cache.remove(tempNode); cache.addLast(tempNode); return tempNode.val; }else{ return -1; } } //如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value public void put(int key, int value) { if(map.containsKey(key)){ //如果存在 Node tempNode = map.get(key); cache.remove(tempNode); Node newNode = new Node(key,value); map.put(key,newNode); cache.addLast(newNode); }else{ //如果不存在 //判断满了没有 if(map.size()==capacity){ //满了--删除最久没访问的 Node first = cache.removeFirst(); map.remove(first.key); //再新添加 } //如果没满 Node node = new Node(key,value); map.put(key,node); cache.addLast(node); } } //定义双向链表的节点 class Node{ int key; int val; Node pre; Node next; //构造 public Node(int key,int val){ this.key = key; this.val = val; } } //定义双向链表 class DoubleList{ int size; Node head,tail; public DoubleList(){ //初始化链表 head = new Node(0,0); tail = new Node(0,0); head.next = tail; tail.pre = head; size = 0; } //末尾添加节点 public void addLast(Node x){ tail.pre.next = x; x.pre=tail.pre; x.next = tail; tail.pre = x; size++; } //删除最近没访问的节点并且返回这个节点--head是虚拟头节点 public Node removeFirst(){ Node first = head.next; head.next = head.next.next; head.next.pre=head; size--; return first; } //删除指定节点 public void remove(Node node){ node.pre.next=node.next; node.next.pre=node.pre; size--; } } } /** * 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); */