1. 程式人生 > 實用技巧 >LRUCache 實現: 雙端佇列 + HashMap快速實現。

LRUCache 實現: 雙端佇列 + HashMap快速實現。

自己實現佇列(啞頭結點+ 啞尾結點實現 + 雙向佇列實現)(快速儲存) + HashMap快速查詢(索引):
主要思路
get:
當快取中不存在,則返回-1;
當快取中存在,則佇列中移除,新增到雙端佇列末尾,返回node.value;
put:思路:
判斷是否存在: 複用get方法:不存在返回-1, 存在返回當前value,並且將節點移動到末尾;
如果不存在,判斷是否記憶體已滿?
滿了,則刪除隊頭結點,以及map中移除索引;
建立新節點,然後新增在佇列末尾,然後新增索引項。

import java.util.*;


public class Solution {
    /**
     * lru design
     * @param operators int整型二維陣列 the ops
     * @param k int整型 the k
     * @return int整型一維陣列
     */
    public int[] LRU (int[][] operators, int k) {
        // write code here
        List<Integer> list = new ArrayList<> ();
        LRUCache cache = new LRUCache(k);
        for(int[] arr : operators){
            if(arr[0] == 1){
                cache.put(arr[1] ,arr[2]);
            } else if(arr[0] == 2){
                //System.out.println(cache.get(arr[1]));
                list.add(cache.get(arr[1]));
            }
        }
        //List<String> ans = new ArrayList<>();
        //ans.toArray(new String[ans.size()]);
        int[] ans = new int[list.size()];
        for(int i = 0; i < list.size(); i++){
           ans[i] = list.get(i);
        }
        return ans;
        //return ans.toArray(new int[ans.size()]);
    }
}
class ListNode {
    ListNode prev;
    ListNode next;
    int key;
    int value;
   
    public ListNode(int key_, int value_){
        key = key_;
        value = value_;
    }
}
class LRUCache{
    ListNode dummyHead = new ListNode(0,0);
    ListNode dummyTail = new ListNode(0,0);
    Map<Integer, ListNode> mp = new HashMap<> ();
    int capacity ;
    public LRUCache(int cap){    
        // 構建雙向佇列
        dummyHead.next = dummyTail;
        dummyTail.prev = dummyHead;
        capacity = cap;
    }
    
    // 查詢
    public int get(int key){
        // 不在快取中
        if(!mp.containsKey(key)){
            return -1;
        }
        ListNode node = mp.get(key);
        // 佇列中刪除+ 加入佇列末尾;
        node.prev.next = node.next;
        node.next.prev = node.prev;
        
        node.next = dummyTail;
        node.prev = dummyTail.prev;
        dummyTail.prev.next = node;
        dummyTail.prev = node;
        return node.value;
    }
    
    //寫入
    public void put(int key, int value){
        //快取裡面是否存在
        //存在 
        if(get(key) > -1){
             mp.get(key).value = value;
        }
        //不存在
        // 記憶體是否已滿
        else {
            if(mp.size() == capacity ){
                //刪除隊首節點
                ListNode node = dummyHead.next;
                //連結串列中刪除頭接待你
                node.prev.next = node.next;
                node.next.prev = node.prev;
                // map中刪除
                mp.remove(node.key);
            }
            
             ListNode newNode = new ListNode(key, value);
            // 新增到末尾
            newNode.next = dummyTail;
            newNode.prev = dummyTail.prev;
            dummyTail.prev.next =  newNode;
            dummyTail.prev =  newNode;
            // 更新mp;
            mp.put(key, newNode);
        }
       
    }
}