Leetcode-146. LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。
进阶:
你是否可以在 O(1) 时间复杂度内完成这两种操作?
示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得密钥 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得密钥 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4
解法:主要是使用双向链表的思想,增加pre和next指针,删除节点,增加到开头
- Java
class LRUCache {
class Node{
Node prev, next;
int key, value;
Node(int k, int v){
key = k;
value = v;
}
}
final Node head = new Node(0, 0);
final Node tail = new Node(0, 0);
final Map<Integer, Node> map;
final int capacity;
public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap(capacity);
head.next = tail;
tail.prev = head;
}
public int get(int key) {
int res = -1;
if(map.containsKey(key)){
Node n = map.get(key);
remove(n);
insertToHead(n);
res = n.value;
}
return res;
}
public void put(int key, int value) {
if(map.containsKey(key)){
Node n = map.get(key);
remove(n);
n.value = value;
insertToHead(n);
} else {
if(map.size() == capacity){
map.remove(tail.prev.key);
remove(tail.prev);
}
Node n = new Node(key, value);
insertToHead(n);
map.put(key, n);
}
}
private void remove(Node n){
n.prev.next = n.next;
n.next.prev = n.prev;
}
private void insertToHead(Node n){
Node headNext = head.next;
head.next = n;
headNext.prev = n;
n.prev = head;
n.next = headNext;
}
}
/** * 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); */
- Python
使用ordereddict
class LRUCache:
def __init__(self, capacity):
self.dic = collections.OrderedDict()
self.remain = capacity
def get(self, key):
if key not in self.dic:
return -1
v = self.dic.pop(key)
self.dic[key] = v # set key as the newest one
return v
def put(self, key, value):
if key in self.dic:
self.dic.pop(key)
else:
if self.remain > 0:
self.remain -= 1
else: # self.dic is full
self.dic.popitem(last=False) # 推出最后的元素
self.dic[key] = value
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)