LeetCode-146:LRU缓存机制

题目描述:

 

 解题分析:

LRU是Least Recently Used,因此在插入元素时候,需要插到最前面;当达到capacity时候,需要把最后一个(即距离上次使用时间最长的那个元素)移除。因此LRU需要以下几个操作:

1、能够添加元素,并且始终将新添加的元素移到缓存最前面;

2、 在添加数据时候,如果缓存满了,需要将最后面的元素移除;

3、查询时候,如果查询到缓存中的数据,返回数据值并将该数据移动到缓存的前面,如果没有查到数据,返回-1;

实现方法:双向链表+哈希表

双向链表作用:一方面通过链表,维护节点之间的顺序,另一方面,双向链表通过伪节点head和tail,可以很方便的将最新的元素插入缓存最前面,或者将最后一个元素移除。

哈希表作用:可以在常数时间内get和put元素。

 

具体代码:(在官方的基础上改的)

 1 import java.util.Hashtable; // Hashtable相对HashMap来说,是线程安全的
 2 public class LRUCache {
 3 
 4   class DLinkedNode { //构建双向链表
 5     int key;
 6     int value;
 7     DLinkedNode prev;
 8     DLinkedNode next;
 9   }
10 
11   private void addNode(DLinkedNode node) {  // 始终将添加的元素放在伪节点head的后面
12     node.prev = head;
13     node.next = head.next;
14     head.next.prev = node;
15     head.next = node;
16   }
17 
18   private void removeNode(DLinkedNode node){  // 移除节点
19     DLinkedNode prev = node.prev;
20     DLinkedNode next = node.next;
21     prev.next = next;
22     next.prev = prev;
23   }
24 
25   private void moveToHead(DLinkedNode node){  // 将节点移动到缓存的前面
26     removeNode(node);
27     addNode(node);
28   }
29 
30   private DLinkedNode popTail() {  // 移除缓存最后面的节点
31     DLinkedNode res = tail.prev;
32     removeNode(res);
33     return res;
34   }
35 
36   private Hashtable<Integer, DLinkedNode> cache =
37           new Hashtable<Integer, DLinkedNode>();
38   private int size;
39   private int capacity;
40   private DLinkedNode head, tail;
41 
42   public LRUCache(int capacity) {  // 初始化缓存,构建以伪节点head和tail为开头和结尾的双向链表
43     this.size = 0;
44     this.capacity = capacity;
45     head = new DLinkedNode();
46     tail = new DLinkedNode();
47     head.next = tail;
48     tail.prev = head;
49   }
50 
51   public int get(int key) {
52     DLinkedNode node = cache.get(key);
53     if (node == null) return -1;
54     moveToHead(node);  // 将节点移动到缓存的前面
55     return node.value;
56   }
57 
58   public void put(int key, int value) {
59     DLinkedNode node = cache.get(key);
60     if(node == null) {  // 如果没有的话,添加到里面,注意缓存是否满了
61       DLinkedNode newNode = new DLinkedNode();
62       newNode.key = key;
63       newNode.value = value;
64       cache.put(key, newNode);
65       addNode(newNode);
66       ++size;
67       if(size > capacity) {
68         DLinkedNode tail = popTail();
69         cache.remove(tail.key);
70         --size;
71       }
72     } else {
73       node.value = value;
74       moveToHead(node);
75     }
76   }
77 }

 

posted @ 2020-05-08 10:26  寻找最优解  阅读(221)  评论(0编辑  收藏  举报