LeetCode 6 LRU Cache
Design and implement a data structure for Least Recently Used cache.It shoud support the follwing operation:get and set.
get(key)-Get the value(will always be positive)of the key if the key exists in the cache,otherswise return-1.
set(key,value)-Set or insert the value if the key is not already present.When the cache reached its capacity,it Shuld invalidate the least recently used item before ineting a new ite.em.
解析:データ構造の実現問題.
1,get(key)とset(key,value)の二つの方法を見て、まずHashMapを使いたいですが、直接にhashMapを使ってkey-valueを保存すれば、要素の訪問時間情報が分かりません.
2,順序情報を維持できるのは、まず配列とチェーンを考え、テーマの意味に従い、ある要素が訪問されたら頭に置いて、また挿入操作があるので、チェーンを使いたいです.
3チェーンテーブルを使用した後、リンクノードはvalue、hashMapはkey-nodeペアを保存し、ノードが訪問された後、このノードを先頭に移動します.このようにして、ノードはアクセスの新旧度に従って配列することができます.capacityを超えたら、一番古いアクセスノードを削除するので、テーブルの最後を指すポインタを維持します.O(1)時間的にノードを削除するためには、双方向チェーンで最適です.
これでほぼ確定しました.
get(key)-Get the value(will always be positive)of the key if the key exists in the cache,otherswise return-1.
set(key,value)-Set or insert the value if the key is not already present.When the cache reached its capacity,it Shuld invalidate the least recently used item before ineting a new ite.em.
解析:データ構造の実現問題.
1,get(key)とset(key,value)の二つの方法を見て、まずHashMapを使いたいですが、直接にhashMapを使ってkey-valueを保存すれば、要素の訪問時間情報が分かりません.
2,順序情報を維持できるのは、まず配列とチェーンを考え、テーマの意味に従い、ある要素が訪問されたら頭に置いて、また挿入操作があるので、チェーンを使いたいです.
3チェーンテーブルを使用した後、リンクノードはvalue、hashMapはkey-nodeペアを保存し、ノードが訪問された後、このノードを先頭に移動します.このようにして、ノードはアクセスの新旧度に従って配列することができます.capacityを超えたら、一番古いアクセスノードを削除するので、テーブルの最後を指すポインタを維持します.O(1)時間的にノードを削除するためには、双方向チェーンで最適です.
これでほぼ確定しました.
public class LRUCache {
//
class DoubleLinkedListNode{
public int key;
public int value;
public DoubleLinkedListNode pre;
public DoubleLinkedListNode next;
public DoubleLinkedListNode(int key, int value){
this.key = key;
this.value = value;
}
}
private int capacity;
private int size;
private HashMap<Integer, DoubleLinkedListNode> map = new HashMap<Integer, DoubleLinkedListNode>();
private DoubleLinkedListNode head;
private DoubleLinkedListNode tail;
public LRUCache(int capacity) {
this.capacity = capacity;
size = 0;
}
//get set
public int get(int key) {
if(map.containsKey(key)){
DoubleLinkedListNode curr = map.get(key);
removeNode(curr);
setHead(curr);
return curr.value;
}else{
return -1;
}
}
public void set(int key, int value) {
if(map.containsKey(key)){
DoubleLinkedListNode curr = map.get(key);
curr.value = value;
removeNode(curr);
setHead(curr);
}else{
DoubleLinkedListNode curr = new DoubleLinkedListNode(key, value);
map.put(key, curr);
setHead(curr);
if(size < capacity){
size++;
}else{
map.remove(tail.key);
removeNode(tail);
}
}
}
// ,
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{
tail = pre;
if(tail != null)
tail.next = null;
}
}
private void setHead(DoubleLinkedListNode node){
node.next = head;
node.pre = null;
if(head != null){
head.pre = node;
}
head = node;
if(tail == null)
tail = node;
}
}