Implement get and set in O (1) time using two-way linked list + map
Note that:
1. Update tail at set.
When the size is 0, the header is updated.
When the size is capacity, the header is deleted and updated.
2. Update the node to the tail position when you get the node, and if the node is the header, update the header.
Code attached:
class LRUCache{ struct Node{ int key; int val; Node* next; Node* pre; Node(int k, int v) { key = k; val = v; next = pre = NULL; } }; Node * head; Node * tail; int size; int cap; map<int, Node*> keyMap;public: LRUCache(int capacity) { head = tail = NULL; cap = capacity; size = 0; keyMap = map<int, Node*>(); } ~LRUCache(){ while (head) { Node * deleteNode = head; head = head->next; delete deleteNode; } } Node * getNode(int key) { if (keyMap.find(key) == keyMap.end()) return NULL; Node* foundNode = keyMap[key]; if (size == 1 || foundNode == tail) return foundNode; if (foundNode == head)//size > 1, foundNode->next is not NULL head = foundNode->next; //remove foundNode from list foundNode->next->pre = foundNode->pre; if (foundNode->pre) foundNode->pre->next = foundNode->next; //update tail tail->next = foundNode; foundNode->pre = tail; tail = tail->next; //update foundNode foundNode->next = NULL; return foundNode; } int get(int key) { Node * foundNode = getNode(key); if (foundNode) return foundNode->val; else return -1; } void set(int key, int value) { Node * foundNode = getNode(key);//put Node to the front of list //if key exists, update value if (foundNode) { foundNode->val = value; return; } //if key not exists, create Node Node * newNode = new Node(key, value); keyMap[key] = newNode; if (size == 0) tail = head = newNode; else { tail->next = newNode; newNode->pre = tail; tail = tail->next; } size++; //check if need delete if (size <= cap) return; Node * deleteNode = head; head = head->next; head->pre = NULL; keyMap.erase(deleteNode->key); delete deleteNode; size--; }};
This is the code I wrote for the first time:
class lrucache {public: struct node {int value; int key; node * Next; node * pre; node (int v, int K) {value = V; key = K; next = pre = 0 ;}}; lrucache (INT capacity) {head = 0; tail = 0; hash = unordered_map (); max_cap = capacity; cur_cap = 0 ;}~ Lrucache () {hash. clear (); node * temp; while (head) {temp = head; head = head-> next; Delete temp;} int get (INT key) {If (hash. find (key )! = Hash. end () {node * cur = hash [Key]; remove (cur); push (cur); Return cur-> value;} return-1 ;} void set (INT key, int value) {If (hash. find (key )! = Hash. end () {node * cur = hash [Key]; remove (cur); push (cur); cur-> value = value;} else if (cur_cap next; If (Head = 0) // The only node that has taken the head = tail = 0; elsehead-> pre = 0; n-> next = 0;} else if (n = tail) // at least 2 nodes, otherwise head = tail = n {tail = tail-> pre; tail-> next = 0; n-> pre = 0 ;} else {n-> pre-> next = N-> next; n-> next-> pre = N-> pre; n-> pre = N-> next = 0 ;}} void push (node * n) // put the node to the end {If (Head = 0) // 0 nodes {head = tail = N;} else // at least one node {tail-> next = N; n-> pre = tail; tail = N ;}} int popnode () // Delete the Start Node {If (Head = 0) // return 0 for 0 nodes; else if (Head = tail) // one node {int key = head-> key; Delete head; head = tail = 0; Return key ;} else // at least 2 nodes {int key = head-> key; head = head-> next; // The head cannot be empty. Delete head-> pre; head-> pre = 0; Return key;} node * head; node * tail; unordered_map hash; int max_cap; int cur_cap ;};
LRU cache [leetcode]