LRU cache

實現 LRU 緩存,

支持 get(key), set(key, value) 操作,並且在 set 時把最近最不常用到的(least used)刪除

如果 set 時 key已經存在則覆蓋 value

這裡我們用雙向鏈表來連接 node,面試時問一下面試官要用什麼,也可以用 array

要注意的是,新進來的值就要是「hit」,所以新進來的值就要移到鏈表尾

當然, get 時如果 hit,就把這個 Node 擺到最後

public class LRUCache {

    private class Node {
        Node prev;
        Node next;
        int key;
        int value;
        public Node(int key, int value) {
            this.key = key;
            this.value = value;
            this.prev = null;
            this.next = null;
        }
    }

    public int capacity;
    private HashMap<Integer, Node> hs = new HashMap<Integer, Node>();
    private Node head = new Node(-1, -1);
    private Node tail = new Node(-1, -1);

    /*
    * @param capacity: An integer
    */
    public LRUCache(int capacity) {
        // do intialization if necessary
        this.capacity = capacity;
        tail.prev = head;
        head.next = tail;
    }

    /*
     * @param key: An integer
     * @return: An integer
     */
    public int get(int key) {
        // write your code here
        if (!hs.containsKey(key)) {
            return -1;
        }

        //remove current
        Node cur = hs.get(key);
        cur.prev.next = cur.next;
        cur.next.prev = cur.prev;

        move_to_tail(cur);
        return hs.get(key).value;
    }

    /*
     * @param key: An integer
     * @param value: An integer
     * @return: nothing
     */
    public void set(int key, int value) {
        // write your code here
        if (get(key) != -1) {   //hit
            hs.get(key).value = value;
            return;
        }

        //check if hs is at full capacity
        if (hs.size() == capacity) {
            hs.remove(head.next.key);    //注意是刪掉最不常用的,也就是 head.next!!!!
            head.next = head.next.next;
            head.next.prev = head;
        }

        Node newNode = new Node(key, value);
        hs.put(key, newNode);
        move_to_tail(newNode);
    }

    //because cur is mostly used so move it to end
    private void move_to_tail(Node cur) {
        cur.prev = tail.prev;
        tail.prev = cur;
        cur.prev.next = cur;
        cur.next = tail;
    }
}

results matching ""

    No results matching ""