This is the 11th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021

Implement the LRUCache class:

  • LRUCache(int capacity) The LRU cache is initialized using a positive integer as capacity

  • Int get(int key) Returns the value of the key if it exists in the cache, otherwise -1 is returned.

  • void put(int key, int value)

    • If the keyword already exists, change its data value;

    • If the keyword does not exist, the set of keyword – values is inserted.

    • When the cache reaches its maximum capacity, it should delete the oldest unused data values before writing new data to make room for new data values.

  • Example:

Input [" LRUCache ", "put", "put", "get", "put", "get", "put", "get", "get", "get"] [[2], [1, 1], [2, 2], [1], [3, 3], [2]. [4, 4], [1], [3], [4] Output [NULL, NULL, NULL, 1, NULL, -1, NULL, -1, 3, 4] LRUCache LRUCache = new LRUCache(2); lRUCache.put(1, 1); // Cache is {1=1} lRUCache. Put (2, 2); {1=1, 2=2} lRUCache. Get (1); // Return 1 lRUCache. Put (3, 3); {1=1, 3=3} lRUCache. Get (2); // return -1 (not found) lRUCache. Put (4, 4); {4=4, 3=3} lRUCache. Get (1); // return -1 (not found) lRUCache. Get (3); // return 3 lRUCache. Get (4); / / return 4Copy the code

Source: LeetCode link: leetcode-cn.com/problems/Or…

Train of thought

  • So the first thing I want to do is I want to make sure thatgetfunction
    • Return -1 if the node is empty, otherwise move the node to the end

    • If the cache is hit, then the node in the corresponding bidirectional list is moved to the end

  • Next, determine the three functions of the bidirectional list, move to the tail, delete elements, insert elements
    • The main thing is to maintain two sentinel nodes, which are shown in the following codehead/tail
    • The last is to construct a bidirectional linked list, determine these steps, the rest is the basic skills of linked list operation

class ListNode{
    public int key;
    public int value;
    public ListNode next;
    public ListNode prev;

    public ListNode(int k, int v) { key = k; value = v; }}class LRUCache {
    private ListNode head;
    private ListNode tail;
    private Map<Integer, ListNode> map;
    int capacity;
    
    public LRUCache(int cap) {
        map = new HashMap<>();
        
        head = new ListNode(-1, -1);
        tail = new ListNode(-1, -1);
        head.next = tail;
        tail.prev = head;
        
        capacity = cap;
    }
    
    public int get(int key) {
        ListNode node = map.get(key);
        if (node == null) {
            return -1;
        }
        
        moveToTail(node, node.value);
        
        return node.value;
    }
    
    public void put(int key, int value) {
        if (map.containsKey(key)) {
            moveToTail(map.get(key), value);
        } else {
            if (map.size() == capacity) {
                ListNode toBeDeleted = head.next;
                deleteNode(toBeDeleted);
                
                map.remove(toBeDeleted.key);
            }
            
            ListNode node = newListNode(key, value); insertToTail(node); map.put(key, node); }}private void moveToTail(ListNode node, int newValue) {
        deleteNode(node);

        node.value = newValue;
        insertToTail(node);
    }
    
    private void deleteNode(ListNode node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
    
    private void insertToTail(ListNode node) { tail.prev.next = node; node.prev = tail.prev; node.next = tail; tail.prev = node; }}Copy the code