標籤:leetcode 演算法 面試
【題目】
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
【題意】
實現LRU策略
取相應的key-value
插入key-value是,需要刪除LRU的item
【思路】
維護一個Map記錄對應的<key, value>對
為了類比key的訪問先後關係,需要維護一個訪問次序列表,越靠後的節點,訪問時間距目前時間越短
而在insert或者訪問key的時候,需要從列表中找到對應的key,並把它調整到列表為。
這裡遇到兩個問題,一個是尋找,另一個是移動到末尾
如果使用順序表,尋找O(n),移動O(n),在cache規模很大時時間代價過高
因此這裡使用雙向鏈表來處理
【代碼】
struct Node{ int key; int val; Node*prev; Node*next; Node(int k, int v): key(k), val(v){ prev=NULL; next=NULL; }};class LRUCache{private:Node* head;Node* tail;int capacity;map<int, Node*>cache;public: LRUCache(int capacity) { this->head = NULL;this->tail = NULL;this->capacity = capacity; }void move2tail(Node* node){if(node==tail)return;if(node==head){head = node->next;head->prev=NULL;tail->next=node;node->prev=tail;tail=node;tail->next=NULL;}else{node->prev->next = node->next;node->next->prev = node->prev;tail->next=node;node->prev=tail;tail=node;tail->next=NULL;}} int get(int key) { if(this->cache.find(key)==this->cache.end())return -1;move2tail(this->cache[key]);return this->cache[key]->val; } void set(int key, int value) { if(this->cache.find(key)==this->cache.end()){//cache中還沒有if(this->capacity==0){//cache已經滿了//刪除頭結點this->cache.erase(head->key);head=head->next;if(head)head->prev=NULL;else tail=NULL;}else{//cache還沒滿this->capacity--;}//添加新節點Node* newNode=new Node(key, value);this->cache[key]=newNode;if(tail){tail->next=newNode;newNode->prev=tail;tail=newNode;tail->next=NULL;}else{head=tail=newNode;}}else{//cache中已經有了this->cache[key]->val = value;move2tail(this->cache[key]);} }};