我是靠谱客的博主 精明棒棒糖,最近开发中收集的这篇文章主要介绍Leetcode之LRU Cache,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目:

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(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.

The cache is initialized with a positive capacity.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LRUCache cache = new LRUCache( 2 /* capacity */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // returns 1
cache.put(3, 3);    // evicts key 2
cache.get(2);       // returns -1 (not found)
cache.put(4, 4);    // evicts key 1
cache.get(1);       // returns -1 (not found)
cache.get(3);       // returns 3
cache.get(4);       // returns 4

代码:

方法一——map,vector:

class LRUCache {
public:
    LRUCache(int capacity) {
        cap = capacity, cur = 0; //cur表示已存放的容量
    }
    
    int get(int key) {
        vector<int>::iterator it = find(v.begin(), v.end(), key); //在vector中找对应的key
        if(it == v.end()) return -1; 
        v.erase(it); 
        v.emplace_back(key); //每次get都将该key置顶
        return m[key];
    }
    
    void put(int key, int value) {
        if(m[key])  //如果原先key中就有值,则覆盖原值,同时置顶该key
        {
            m[key] = value;
            vector<int>::iterator it = find(v.begin(), v.end(), key);
            v.erase(it);
            v.emplace_back(key);
            return;
        }
                
        if(cur == cap)
        {
            int p = v.front();
            m[p] = 0;
            v.erase(v.begin());
            m[key] = value;
            v.emplace_back(key);
        }
        else
        {
            cur++;
            v.emplace_back(key);
            m[key] = value;
        }
    }
    int cap, cur;
    vector<int> v;
    map<int, int> m;
};

/**
 * 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);
 */

方法二——双向链表:

class LRUCache {
private:
	int capacity;
	int capacity_cur;
	typedef struct ListNode
	{
		int key;
		int value;
		struct ListNode* next;
		struct ListNode* pre;
		ListNode(int k , int v):key(k),value(v),next(NULL),pre(NULL) {}
	}ListNode;
	ListNode *head;
	
	typedef struct Value
	{
		int val;
		ListNode *p;
		Value(int _v,ListNode *pp):val(_v),p(pp){}
		Value() {}  //if this constructor is not defined,there will be wrong
	}tValue;
	map< int,tValue > mkv;
	map< int,tValue > :: iterator it;
public:
    LRUCache(int capacity) {
       this->capacity = capacity;
		head = new ListNode(0,0);
		capacity_cur = 0;
    }
    
    int get(int key) {
       if( is_exist(key) )  
		{
			//get down the loc node
			ListNode *loc = mkv[key].p;
			loc->pre->next = loc->next;
			loc->next->pre = loc->pre;
 
			//insert into the front of the head
			loc->next = head->next;
			loc->pre = head;
			head->next = loc;
			loc->next->pre = loc;
 
			return mkv[key].val;
		}
		else
		{
			return -1;
		}
    }
    
    void put(int key, int value) {
       if(  is_exist(key) ) 
		{
			mkv[key].val = value;
			ListNode *q = mkv[key].p;
			q->value = value;
           
            ListNode *loc = mkv[key].p;
			loc->pre->next = loc->next;
			loc->next->pre = loc->pre;
 
			//insert into the front of the head
			loc->next = head->next;
			loc->pre = head;
			head->next = loc;
			loc->next->pre = loc;
			return ;
		}
 
		ListNode *tmp = new ListNode(key,value);
		if(capacity_cur<capacity)
		{
			if(head->next==NULL) //the list is empty
			{
				head->next = tmp ;
				head->pre = tmp;
				tmp->next = head;
				tmp->pre = head;
				tValue tv(value,tmp);
				mkv[key] = tv;
				++capacity_cur;
			}
			else //insert the tmp into the front of the list
			{
				tmp->next = head->next;
				tmp->pre = head;
				head->next->pre = tmp;
				head->next = tmp;
				tValue tv(value,tmp);
				mkv[key] = tv;
				++capacity_cur;
			}
		}
		else
		{
			//get rid of the lru node
			ListNode *tail = head->pre;
			head->pre = tail->pre;
			tail->pre->next = head;
			mkv.erase(tail->key);
			delete tail;
		
			//insert into the new node
			tmp->next = head->next;
			tmp->pre = head;
			head->next->pre = tmp;
			head->next = tmp;
			tValue tv(value,tmp);
			mkv[key] = tv;
		}
    }
    bool is_exist(int key)
	{
		return ( mkv.find(key) != mkv.end() );
	}
};

/**
 * 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);
 */

 

最后

以上就是精明棒棒糖为你收集整理的Leetcode之LRU Cache的全部内容,希望文章能够帮你解决Leetcode之LRU Cache所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部