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.public class LRUCache {
HashMap<Integer, DoubleLinkedListNode> map;
DoubleLinkedListNode head;
DoubleLinkedListNode end;
private int capacity;
private int len;
public LRUCache(int capacity) {
this.map = new HashMap<Integer, DoubleLinkedListNode>();
this.capacity = capacity;
this.len = 0;
}
public int get(int key) {
if(map.containsKey(key)) {
DoubleLinkedListNode node = map.get(key);
removeNode(node);
setHead(node);
return node.val;
} else {
return -1;
}
}
private void removeNode(DoubleLinkedListNode node) {
DoubleLinkedListNode pre = node.pre;
DoubleLinkedListNode next = node.next;
if(pre!=null) {
pre.next = next;
} else {
head = next;
}
if(next!=null) {
next.pre = pre;
} else {
end = pre;
}
}
private void setHead(DoubleLinkedListNode node) {
node.next = head;
node.pre = null;
if(head!=null) {
head.pre = node;
}
head = node;
if(end==null) {
end = node;
}
}
public void set(int key, int value) {
if(map.containsKey(key)) {
DoubleLinkedListNode oldNode = map.get(key);
oldNode.val = value;
removeNode(oldNode);
setHead(oldNode);
} else {
DoubleLinkedListNode newNode = new DoubleLinkedListNode(key, value);
if(len<capacity) {
setHead(newNode);
map.put(newNode.key, newNode);
len++;
} else {
map.remove(end.key);
end = end.pre;
if(end!=null) {
end.next = null;
}
setHead(newNode);
map.put(newNode.key, newNode);
}
}
}
class DoubleLinkedListNode{
int val;
int key;
DoubleLinkedListNode pre;
DoubleLinkedListNode next;
public DoubleLinkedListNode(int key, int val) {
this.val = val;
this.key = key;
}
}
}
public class LRUCache {
private int capacity;
private HashMap<Integer, DoubleLinkNode> map;
private DoubleLinkNode head;
private DoubleLinkNode tail;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<Integer, DoubleLinkNode>();
head = new DoubleLinkNode(0, 0);
tail = new DoubleLinkNode(0, 0);
head.next = tail;
tail.pre = head;
}
private void setToHead(DoubleLinkNode node) {
// swap to head;
if(node.pre!=head) {
if(node.pre!=null)
node.pre.next = node.next;
if(node.next!=null)
node.next.pre = node.pre;
DoubleLinkNode tmpNext = head.next;
tmpNext.pre = node;
node.next = tmpNext;
node.pre = head;
head.next = node;
}
}
public int get(int key) {
if(map.containsKey(key)) {
DoubleLinkNode node = map.get(key);
setToHead(node);
return node.val;
} else {
// error here
return -1;
}
}
public void set(int key, int value) {
if(map.containsKey(key)) {
DoubleLinkNode node = map.get(key);
node.val = value;
setToHead(node);
} else {
if(this.map.size()==this.capacity) {
DoubleLinkNode remove = tail.pre;
DoubleLinkNode tmp = remove.pre;
tail.pre = tmp;
tmp.next = tail;
this.map.remove(remove.key);
}
DoubleLinkNode node = new DoubleLinkNode(key, value);
this.map.put(key, node);
setToHead(node);
}
}
static class DoubleLinkNode {
DoubleLinkNode pre;
DoubleLinkNode next;
int val;
int key;
public DoubleLinkNode(int key, int val) {
this.val = val;
this.key = key;
}
}
}
=========
public class LRUCache {
public static class DoubleLinkedList {
DoubleLinkedList prev;
DoubleLinkedList next;
private int key;
private int val;
public DoubleLinkedList(int key, int val) {
this.key = key;
this.val = val;
}
}
HashMap<Integer, DoubleLinkedList> map;
DoubleLinkedList head;
DoubleLinkedList tail;
int capacity;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<Integer, DoubleLinkedList>();
}
public int get(int key) {
if (!map.containsKey(key)) return -1;
DoubleLinkedList node = map.get(key);
moveToFront(node);
return node.val;
}
public void set(int key, int value) {
if (map.containsKey(key)) {
DoubleLinkedList node = map.get(key);
node.val = value;
moveToFront(node);
} else {
DoubleLinkedList node = new DoubleLinkedList(key, value);
if (head == null) {
head = node;
tail = node;
} else {
node.next = head;
head.prev = node;
head = node;
}
map.put(node.key, node);
if (map.size() > capacity) {
map.remove(tail.key);
tail = tail.prev;
tail.next = null;
}
}
}
private void moveToFront(DoubleLinkedList node) {
if (node == head) {
return;
}
if (node == tail) {
tail = node.prev;
}
DoubleLinkedList oldPrev = node.prev;
DoubleLinkedList oldNext = node.next;
if (oldPrev != null) {
oldPrev.next = oldNext;
}
if (oldNext != null) {
oldNext.prev = oldPrev;
}
node.next = head;
head.prev = node;
head = node;
}
}
没有评论:
发表评论