LRU缓存机制-LeetCode

Leetcode刷题笔记-146.LRU缓存机制

算法思想

链接: https://leetcode-cn.com/problems/lru-cache/.
题目中给予了两个函数,get和put函数,并且要求时间复杂度为O(1)。
put约束条件如下:
(1)关键字存在:变更数据。
(2)关键字不存在:判断缓存容量是否达到上限:达到了上限,则应该删除最久未使用的数据;未达上限,直接添加。
get约束条件如下:
如果关键字在缓存,获取该关键字的值,否则返回-1。

此题目要求的数据结构需要满足:查找快、插入、删除快且有顺序之分的特点。

  • 查找快且时间复杂度为O(1),我们可以想到哈希表这种数据结构(可以看成“数组+链表 ”,类似c语言中“指针数组”)。具有查找快特点。

  • 有顺序之分(用于区分最近使用和最久未使用的数据)、插入快、删除快我们可以想到链表这种数据结构。

于是结合两个数据结构我们可以得到一种新的数据结构:哈希链表。此题用这种数据结构就可解决。
在这里插入图片描述

代码

class LRUCache {
    private:
    int cap;
    list<pair<int,int>> _list; //声明一个由键值对组成的双向链表list
    unordered_map<int,list<pair<int,int>>::iterator> map; //hash表,map相当于数组+链表
public:
    LRUCache(int capacity) {
        this->cap=capacity;
    }
    
    int get(int key) {
        auto it=map.find(key);  //指向list的指针
        if(it==map.end()) return -1; //查到结尾没查到
        // key 存在,把 (k, v) 换到队头
        pair<int,int> kv=*map[key]; //创建list节点,map[key]即指向list结点的指针
        _list.erase(map[key]);  //删除节点
        _list.push_front(kv);   //插入节点
        // 更新 (key, value) 在 list 中的位置
        map[key]=_list.begin();
        return kv.second;
    }
    
    void put(int key, int value) {
         /* 要先判断 key 是否已经存在 */ 
        auto it=map.find(key);
        if(it==map.end()){
            /* key 不存在,判断 list 是否已满 */ 
            if(_list.size()==cap){
                // list 已满,删除尾部的键值对位置
                // list 和 map 中的数据都要删除
                auto lastPair =_list.back(); //指向链表尾部节点
                int lastKey=lastPair.first; //取出key值
                map.erase(lastKey);
                _list.pop_back();
            }
              // list 没满,可以直接添加 
            _list.push_front(make_pair(key,value)); //创建一个对组
            map[key]=_list.begin();
        }
        else{
             /* key 存在,更改 value 并换到队头 */
             _list.erase(map[key]);
             _list.push_front(make_pair(key,value));
             map[key]=_list.begin();
        }
    }
};

代码原作者:labuladong
转载链接: https://leetcode-cn.com/problems/lru-cache/solution/lru-ce-lue-xiang-jie-he-shi-xian-by-labuladong/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值