Skip to content

Latest commit

 

History

History
159 lines (136 loc) · 3.55 KB

146.md

File metadata and controls

159 lines (136 loc) · 3.55 KB

Solution

Doubly Linked List + HashMap.

import java.util.HashMap;

public class LRUCache {
    class Entry {
        int key;
        int val;
        Entry after;
        Entry before;
        public Entry(int key, int value) {
            this.key = key;
            this.val = value;
        }

        public Entry() {
            this(0, 0);
        }
    }

    private HashMap<Integer, Entry> map;
    int capacity, size;
    private Entry head, tail;

    public LRUCache(int cap) {
        map = new HashMap<>();
        capacity = cap;
        head = new Entry();
        tail = new Entry();
        head.after = tail;
        tail.before = head;
    }

    public int get(int key) {
       Entry node = map.get(key);
       if (node == null) {
           return -1;
       }
       updateEntry(node);
       return node.val;
    }

    public void put(int key, int value) {
        Entry node = map.get(key);
        if (node == null) {
            Entry newNode = new Entry(key, value);
            map.put(key, newNode);
            addEntry(newNode);
            size++;
        } else {
            node.val = value;
            updateEntry(node);
        }
        if (size > capacity) {
            Entry toDel = tail.before;
            deleteEntry(toDel);
            map.remove(toDel.key);
            size--;
        }
    }

    public void updateEntry(Entry node) {
        deleteEntry(node);
        addEntry(node);
    }

//    add node to front (most recently used)
    public void addEntry(Entry node) {
        node.before = head;
        node.after = head.after;
        head.after = node;
        node.after.before = node;

    }

//    remove node from rear (least recently used)
    public void deleteEntry(Entry node) {
        node.before.after = node.after;
        node.after.before = node.before;
    }

}
class LRUCache(object):

    class Entry:
        def __init__(self, key, value):
            self.key = key
            self.value = value
            self.after = None
            self.before = None

    def __init__(self, capacity):
        """
        :type capacity: int
        """
        self.map = dict()
        self.size = 0
        self.capacity = capacity
        self.head = self.Entry(0, 0)
        self.tail = self.Entry(0, 0)
        self.head.after = self.tail
        self.tail.before = self.head


    def get(self, key):
        """
        :type key: int
        :rtype: int
        """
        node = self.map.get(key, None)
        if node == None:
            return -1

        self.updateEntry(node)
        return node.value

    def put(self, key, value):
        """
        :type key: int
        :type value: int
        :rtype: None
        """
        node = self.map.get(key, None)

        if node == None:
            self.size += 1
            entry = self.Entry(key, value)
            self.map[key] = entry
            self.addEntry(entry)
        else:
            node.value = value
            self.updateEntry(node)

        if self.size > self.capacity:
            self.size -= 1
            toDel = self.tail.before
            self.deleteEntry(toDel)
            self.map.pop(toDel.key)

    def updateEntry(self, entry):
        self.deleteEntry(entry)
        self.addEntry(entry)

    def deleteEntry(self, entry):
        prev, next = entry.before, entry.after
        prev.after = next
        next.before = prev

    def addEntry(self, entry):
        entry.before = self.head
        entry.after = self.head.after
        self.head.after.before = entry
        self.head.after = entry