LRU Cache

Published by

on

Problem

https://leetcode.com/problems/lru-cache/description/

Solution

class Node {
    int key;
    int value;
    Node prev;
    Node next;

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

class LRUCache {
    Map<Integer, Node> map;
    int capacity;
    Node head;
    Node tail;

    public LRUCache(int capacity) {
        this.map = new HashMap<>();
        this.capacity = capacity;
        initialize();
    }

    private void initialize() {
        this.head = new Node(-1, -1); // Dummy Node
        this.tail = new Node(-1, -1); // Dummy Node
        
        this.head.next = this.tail;
        this.tail.prev = this.head;
    }
    
    public int get(int key) {
        if (map.containsKey(key)) {
            // Get node from map
            Node node = map.get(key);
            
            // Move node to the last
            removeNode(node);
            addLast(key, node);

            return node.value;
        } else {
            return -1;
        }
    }
    
    public void put(int key, int value) {
        if (map.containsKey(key)) {
            // Move node to the last
            Node node = map.get(key);
            removeNode(node);
            addLast(key, new Node(key, value));
        } else {
            if (map.keySet().size() == capacity) {
                // Remove head
                removeHead();
            } 
            // Add node to the last
            addLast(key, new Node(key, value));
        }
    }

    private void removeHead() {
        Node realHead = head.next;
        
        map.remove(realHead.key);
        head.next = realHead.next;
        realHead.next.prev = head;
    }

    private void removeNode(Node node) {
        map.remove(node.key);

        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private void addLast(int key, Node node) {
        map.put(key, node);

        Node realTail = tail.prev;
        realTail.next = node;
        node.prev = realTail;
        
        node.next = tail;
        tail.prev = node;
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */
  • Dummy node 를 이용해서 linked list 를 구하는 것이 key point 였던 문제!
    • head, tail 을 dummy node 으로 구성해서, 실제로 값이 없어도 head, tail 은 항상 존재할 수 있도록!(그래야 연산이 쉬워짐)
  • LinkedList 를 구성할때는 직접 list 를 사용하는 것 외에도, Node 라는 클래스를 만들고, prev, next 포인터를 이용해서 풀 수 있다.

Leave a comment