Problem Statement

Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.

Implement the LRUCache class:

The functions get and put must each run in O(1) average time complexity.

Example 1:

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]

Explanation
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // cache is {1=1}
lRUCache.put(2, 2); // cache is {1=1, 2=2}
lRUCache.get(1);    // return 1
lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}
lRUCache.get(2);    // returns -1 (not found)
lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3}
lRUCache.get(1);    // return -1 (not found)
lRUCache.get(3);    // return 3
lRUCache.get(4);    // return 4

Constraints:

Problem Link

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

Code

class LRUCache {
public:
    int capacity;
    struct Node {
        int key;
        int val;
        Node* next;
        Node* prev;
        Node(int x,int y) {
            key = x;
            val = y;
            Node *next = NULL;
            Node *prev = NULL;
        }
    };
    Node* head = NULL;
    Node* tail = NULL;

    unordered_map<int,Node*> m;

    LRUCache(int capacity) {
        this->capacity = capacity;
        head = new Node(-1,-1);
        tail = new Node(-1,-1);
        head->next = tail;
        tail->prev = head;

    }

    void insertAtFront(Node *node) {

        node->next = head->next;
        node->prev = head;
        head->next->prev = node;
        head->next = node;
    
    }

    void Delete(Node *node) {
        node->next->prev = node->prev;
        node->prev->next = node->next;
    }
    
    int get(int key) {
       if(m.find(key)!=m.end()) {
            Delete(m[key]);
            insertAtFront(m[key]);
            return m[key]->val;
        }

        return -1;
    }
    
    void put(int key, int value) {
       
      
    

    if(m.find(key)!=m.end()) {
        Delete(m[key]);
        insertAtFront(m[key]);
        m[key]->val = value;
        
    } else {
        Node *node = new Node(key,value);
        m[key] = node;
        if(capacity>0) {
           insertAtFront(node);
           capacity--;
       } else {
          Node *delNode = tail->prev;
          Delete(delNode);
          m.erase(delNode->key);
          insertAtFront(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);
 */