首页 > 代码库 > LeetCode: LRU Cache [146]

LeetCode: LRU Cache [146]

【题目】

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策略

        1. 依据key取value

        2. 插入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]);
		}
    }
};