146. LRU Cache
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get
and put
.
get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.put(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.
Follow up:
Could you do both operations in O(1) time complexity?
Example:
LRUCache cache = new LRUCache( 2 /* capacity */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // returns 1 cache.put(3, 3); // evicts key 2 cache.get(2); // returns -1 (not found) cache.put(4, 4); // evicts key 1 cache.get(1); // returns -1 (not found) cache.get(3); // returns 3 cache.get(4); // returns 4
public class Node<T, D>
{
public T data;
public D name;
public Node<T, D> next;
public Node<T, D> pre;
}
public class NodeList<T, D>
{
//List<Node<T>> _nodeList = new List<Node<T>>();
Node<T, D> head;
Node<T, D> tail;
public void Add(Node<T, D> node)
{
if (null == head)
{
head = node;
tail = node;
return;
}
head.next = node;
node.pre = head;
node.next = null;
head = node;
}
public Node<T, D> GetHead()
{
return head;
}
public Node<T, D> GetTail()
{
return tail;
}
public void RemoveTail()
{
if (null == tail)
{
return;
}
if (tail.next != null)
{
tail = tail.next;
tail.pre = null;
}
else
{
tail = null;
}
}
public void MoveToFirst(Node<T, D> node)
{
if (head == node)
{
return;
}
if (node == tail)
{
tail = node.next;
tail.pre = null;
}
if (node.pre != null)
{
node.pre.next = node.next;
node.next.pre = node.pre;
}
head.next = node;
node.next = null;
node.pre = head;
head = node;
}
}
public class LRUCache
{
Dictionary<int,Node<int,int>> _dict = new Dictionary<int,Node<int,int>>();
NodeList<int, int> _keyList = new NodeList<int, int>();
int _capacity;
public LRUCache(int capacity)
{
_capacity = capacity;
}
public int Get(int key)
{
Node<int,int> val;
if (_dict.TryGetValue(key, out val))
{
_keyList.MoveToFirst(val);
return val.data;
}
else
{
return -1;
}
}
public void Put(int key, int value)
{
Node<int,int> val;
if (0 == _capacity)
{
return;
}
if (_dict.TryGetValue(key, out val))
{
_dict[key].data = value;
_keyList.MoveToFirst(_dict[key]);
}
else
{
if (_dict.Count == _capacity)
{
var item = _keyList.GetTail();
_dict.Remove(item.name);
_keyList.RemoveTail();
}
Node<int, int> node = new Node<int, int>();
node.name = key;
node.data = value;
_keyList.Add(node);
_dict.Add(key,node);
}
}
}