[leetcode] 【链表】 146. LRU Cache

来源:互联网 发布:e63诺基亚软件下载网址 编辑:程序博客网 时间:2024/05/24 00:28

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算法。支持get和set操作。

get  获取key对应的value值,如果没有这个key则返回-1;

set  给key赋value的值,如果key不存在则插入key-value对;    当缓存满了的时候,删除最近最少使用的键值对,然后再插入新的键值对之。

 

题解

 LRU是一种应用在操作系统上的缓存替换策略,和我们常见的FIFO算法一样,都是用于操作系统中内存管理中的页面替换,其全称叫做Least Recently Used(近期最少使用算法),算法主要是根据数据的历史访问记录来进行数据的淘汰,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

为了能够比较形象的了解LRU的执行过程,我们举一个例子,如下:

假定现有一进程的页面访问序列为:

4,7,0,7,1,0,1,2,1,2,6

缓存容量为5,则随着进程的访问,缓存栈中页面号的变化情况如下图所示。在访问页面6时发生了缺页,此时页面4是最近最久未被访问的页,应将它置换出去。


如此,使用双链表是最好实现数据操作的数据结构了。因为数据被访问的时候需要把这个数据移到链表最前面,这样最近没有被访问的数据将处于链表的最后面。如图:


查找的话还需要hashmap这个数据结构。

class LRUCache{public:    LRUCache(int capacity) {        m_capacity=capacity;    }        int get(int key) {        int res=-1;        auto it =cache_map.find(key);        if(it!=cache_map.end())        {            res=it->second->second;            list<pair<int,int> > ::iterator  temp_list=it->second;            pair<int,int> temp_pair=*temp_list;            cache.erase(temp_list);            cache.push_front(temp_pair);                        cache_map[key]=cache.begin();//更新map中  链表键值对的指针        }        return res;    }        void set(int key, int value) {        auto it =cache_map.find(key);        if(it!=cache_map.end())        {            list<pair<int,int> > ::iterator  temp_list=it->second;            temp_list->second=value;            pair<int,int> temp_pair=*temp_list;            cache.erase(temp_list);            cache.push_front(temp_pair);            cache_map[key]=cache.begin();//更新map中  链表键值对的指针        }        else        {            pair<int,int> temp_pair=make_pair(key,value);                        if(m_capacity==cache.size())            {                int old_key=cache.back().first;                cache.pop_back();                                auto del =cache_map.find(old_key);                cache_map.erase(del);            }            cache.push_front(temp_pair);            cache_map[key]=cache.begin();//更新map中  链表键值对的指针        }    }    private:    int m_capacity;    list<pair<int,int> > cache;    map< int, list<pair<int, int> > :: iterator> cache_map;  };




0 0
原创粉丝点击