概述
原题网址:https://leetcode.com/problems/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.
方法:使用双向链表保存key的访问顺序,使用哈希映射来快速定位到链表的节点,以便进行移动操作。
public class LRUCache {
private LinkNode head;
private LinkNode tail;
private Map<Integer, LinkNode> map;
private int capacity;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>(capacity);
}
public int get(int key) {
// System.out.println("Getting " + key);
LinkNode node = map.get(key);
if (node == null) return -1;
// System.out.println("Got Node(" + node.value + ")");
if (node == tail) return node.value;
if (node == head) {
this.head = node.next;
node.next.previous = null;
node.next = null;
this.tail.next = node;
node.previous = this.tail;
this.tail = node;
} else {
node.next.previous = node.previous;
node.previous.next = node.next;
node.next = null;
node.previous = this.tail;
this.tail.next = node;
this.tail = node;
}
return node.value;
}
public void set(int key, int value) {
// System.out.println("Setting key " + key + "= " + value);
if (this.capacity <= 0) return;
LinkNode node = map.get(key);
if (node != null) {
node.value = value;
if (node == tail) return;
if (node == head) {
this.head = node.next;
node.next.previous = null;
node.next = null;
this.tail.next = node;
node.previous = this.tail;
this.tail = node;
} else {
node.next.previous = node.previous;
node.previous.next = node.next;
node.next = null;
node.previous = this.tail;
this.tail.next = node;
this.tail = node;
}
} else if (this.map.size() < this.capacity) {
node = new LinkNode(key, value);
map.put(key, node);
if (head == null) {
head = node;
tail = node;
} else {
this.tail.next = node;
node.previous = this.tail;
this.tail = node;
}
} else {
// System.out.println("Setting key " + key + "= " + value + ", replacing");
node = new LinkNode(key, value);
map.remove(this.head.key);
map.put(key, node);
if (this.capacity == 1) {
// System.out.println("Setting key " + key + "= " + value + ", capacity=1");
this.head = node;
this.tail = node;
} else {
this.head.next.previous = null;
this.head = this.head.next;
this.tail.next = node;
node.previous = this.tail;
this.tail = node;
}
}
}
}
class LinkNode {
int key;
int value;
LinkNode previous, next;
public LinkNode(int key, int value) {
this.key = key;
this.value = value;
}
}
封装简化:
public class LRUCache {
private Cache head = new Cache(0, 0);
private Cache tail = new Cache(0, 0);
{
head.insert(tail);
}
private Map<Integer, Cache> map = new HashMap<>();
private int capacity;
public LRUCache(int capacity) {
this.capacity = capacity;
}
public int get(int key) {
Cache cache = map.get(key);
if (cache == null) return -1;
cache.remove();
cache.insert(tail);
return cache.value;
}
public void set(int key, int value) {
if (capacity <= 0) return;
Cache cache = map.get(key);
if (cache == null) {
cache = new Cache(key, value);
cache.insert(tail);
if (map.size() >= capacity) {
map.remove(head.right.key);
head.right.remove();
}
map.put(key, cache);
} else {
cache.value = value;
cache.remove();
cache.insert(tail);
}
}
}
class Cache {
int key, value;
Cache left, right;
Cache(int key, int value) {
this.key = key;
this.value = value;
}
void remove() {
if (this.left != null) this.left.right = this.right;
if (this.right != null) this.right.left = this.left;
this.left = null;
this.right = null;
}
void insert(Cache before) {
this.left = before.left;
if (this.left != null) this.left.right = this;
before.left = this;
this.right = before;
}
}
最后
以上就是纯情鸵鸟为你收集整理的LeetCode 146. LRU Cache(LRU缓存)的全部内容,希望文章能够帮你解决LeetCode 146. LRU Cache(LRU缓存)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复