137.(146)LRU缓存机制

题目描述:

运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

进阶:

你是否可以在 O(1) 时间复杂度内完成这两种操作?

示例:

LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // 返回  1
cache.put(3, 3);    // 该操作会使得关键字 2 作废
cache.get(2);       // 返回 -1 (未找到)
cache.put(4, 4);    // 该操作会使得关键字 1 作废
cache.get(1);       // 返回 -1 (未找到)
cache.get(3);       // 返回  3
cache.get(4);       // 返回  4

思路:

1、使用unordered_map和双向链表,存储数据

2、get() 数据后,将找到的数据添加到链表表头

3、put() 数据后,不需要删除,则在unordered_map中添加,以及在链表表头添加

4、put() 数据后,需要删除的话,删除链表表尾的数据,删除对应的unordered_map里的数据

代码:

struct DoubleList
{
    int key;
    int val;
    DoubleList *pre;
    DoubleList *next;
    DoubleList():pre(nullptr),next(nullptr){}
    DoubleList(int k,int v):key(k),val(v),pre(nullptr),next(nullptr){}
};
class LRUCache {
public:
    int len;
    unordered_map<int,int>ache;
    DoubleList *head,*tail;
    LRUCache(int capacity) {
        len=capacity;
        head = new DoubleList();
        tail = new DoubleList();
        head->next=tail;
        tail->pre=head;
    }
    
    int get(int key) {
        auto it=ache.find(key);
        if(it!=ache.end())
        {
            moveHead(key);
            return (it->second);
        }
        else
            return -1;
    }
    
    void put(int key, int value) {
        auto it=ache.find(key);
        if(it!=ache.end())
        {
            it->second=value;
            moveHead(key);
        } 
        else
        {
            if(ache.size()==len)
            {
                int delete_key=deleteLast();
                ache.erase(delete_key);
            }
            ache.insert({key,value});
            add(key,value);
        }
    }
    void add(int k,int v)
    {
        DoubleList *temp=new DoubleList(k,v);
        temp->next=head->next;
        head->next->pre=temp;
        temp->pre=head;
        head->next=temp;
    }
    int deleteLast()
    {
        int key;
        DoubleList *temp = tail->pre;
        tail->pre=tail->pre->pre;
        tail->pre->next=tail;
        key=temp->key;
        delete temp;
        return key;
    }
    void moveHead(int k)
    {
        DoubleList *temp;
        temp=head->next;
        while(temp!=tail)
        {
            if(temp->key==k)
            {
                temp->pre->next=temp->next;
                temp->next->pre=temp->pre;
                temp->next=head->next;
                head->next->pre=temp;
                head->next=temp;
                temp->pre=head;
                break;
            }
            temp=temp->next;
        }
    }
};

执行效率:

执行用时:304 ms, 在所有 C++ 提交中击败了8.75%的用户

内存消耗:37.3 MB, 在所有 C++ 提交中击败了92.86%的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值