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)時間的にノードを削除するためには、双方向チェーンで最適です.
これでほぼ確定しました.
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;
    }
}