标签:leetcode
使用双向链表+map,实现O(1)时间内的get和set
需要注意的是:
1. set时更新tail
size为0时更新头部
size为capacity时删除头部并且更新头部
2. get时更新节点到tail的位置,同时如果是节点是头部的话要更新头部
附上代码:
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--; } };
这是我第一次写的时候的代码:
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<int, Node*>(); 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 < max_cap)//没有满 { cur_cap++; Node* newNode = new Node(value, key); hash[key] = newNode; push(newNode); } else { Node* newNode = new Node(value, key); hash[key] = newNode; push(newNode); int key = popNode(); hash.erase(key); } } private: void remove(Node * n)//将节点从链表里取出,但是不释放空间 { if (n == head)//n的前面没有节点 { head = head->next; if (head == 0)//唯一一个节点已经拿走 head = tail = 0; else head->pre = 0; n->next = 0; } else if (n == tail)//至少2个节点,否则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)//将节点放入尾部 { if (head == 0)//0个节点 { head = tail = n; } else//至少一个节点 { tail->next = n; n->pre = tail; tail = n; } } int popNode()//删除最开始的节点 { if (head == 0)//0个节点 return 0; else if (head == tail)//一个节点 { int key = head->key; delete head; head = tail = 0; return key; } else//至少2个节点 { int key = head->key; head = head->next;//head不可能为空 delete head->pre; head->pre = 0; return key; } } Node * head; Node * tail; unordered_map<int, Node*> hash; int max_cap; int cur_cap; };
标签:leetcode
原文地址:http://blog.csdn.net/peerlessbloom/article/details/39861699