[LeetCode]146. LRU Cache

LRU(Least Recently Used)是一种常用的页面替换算法,用于内存管理。本文介绍了LRU的工作原理,并通过C++实现了一个LRU缓存,利用双向链表和HashMap进行数据存储与查找。在操作数据时,通过splice方法优化了元素的移动,提高了效率。
摘要由CSDN通过智能技术生成

LRU介绍

LRU是Least Recently Used 近期最少使用算法。 内存管理的一种页面置换算法,对于在内存中但又不用的数据块(内存块)叫做LRU,操作系统会根据哪些数据属于LRU而将其移出内存而腾出空间来加载另外的数据。

利用一个双向链表<c++ list>和一个HashMap<c++ unordered_map>来快速定位数据:

  1. set数据时候,需要先看是否已经有key对应元素,如果有,则需要更改value值,由于LRU,所以需要把这个元素放到链表的表头,可以先删除再创建到表头,也可以利用list的splice方法进行移动
  2. get数据时候需要看是否存在key,不存在返回-1即可,存在需要进行移动,可以先删除然后创建链表头元素,也可以splice进行移动数据。

list介绍

c++中list是双向链表的实现,具有以下方法:

// 将x的i处的元素移动到position处,替代删除然后插入
void splice (iterator position, list& x, iterator i);

// 删除数据: 某个位置,链表尾部,链表头部
iterator erase (iterator position);
void pop_back();
void pop_front();

// 获取元素
reference back();
reference front();

// 链表尾部&头部插入数据,中间位置插入
void push_back (const value_type& val);
void push_front (const value_type& val);
iterator insert (iterator position, const value_type& val);

// 遍历
begin end

代码实现

删除重建方式:

class LRUCache {
private:
    int _capacity;
    list<pair<int, int>> items;
    unordered_map<int, list<pair<int, int>>::iterator> mmap;
public:
    LRUCache(int capacity) {
        _capacity = capacity;    
    }
    
    int get(int key) {
        if (mmap.count(key)) {
            int value = mmap[key]->second;
            items.erase(mmap[key]);
            items.push_front(make_pair(key, value));
            mmap[key] = items.begin();
            return value;
        } else {
            return -1;
        }
    }
    
    void put(int key, int value) {
        if (mmap.count(key) == 0) {
            if (mmap.size() == _capacity) {
                mmap.erase(items.back().first);
                items.pop_back();
            }
            items.push_front(make_pair(key, value));
            mmap[key] = items.begin();
        } else {
            items.erase(mmap[key]);
            items.push_front(make_pair(key, value));
            mmap[key] = items.begin();
        }
    }
};

利用splice方法优化方法:

class LRUCache {
private:
    int _capacity;
    list<pair<int, int>> items;
    unordered_map<int, list<pair<int, int>>::iterator> mmap;
public:
    LRUCache(int capacity) {
        _capacity = capacity;    
    }
    
    int get(int key) {
        if (mmap.count(key)) {
            items.splice(items.begin(), items, mmap[key]);
            mmap[key] = items.begin();
            return mmap[key]->second;
        } else {
            return -1;
        }
    }
    
    void put(int key, int value) {
        if (mmap.count(key) == 0) {
            if (mmap.size() == _capacity) {
                mmap.erase(items.back().first);
                items.pop_back();
            }
            items.push_front(make_pair(key, value));
            mmap[key] = items.begin();
        } else {
            mmap[key]->second = value;
            items.splice(items.begin(), items, mmap[key]);
            mmap[key] = items.begin();
        }
    }
};

参考

  1. http://www.cplusplus.com/reference/list/list/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值