zoukankan      html  css  js  c++  java
  • LRU Cache

    题意:

    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是在操作系统中,最近最久未被使用的,根据cache的大小,每当有一个进程来到时,都要根据当前的情况而做一些改变。

    set:如果当前来到的key在cache中,则将该节点删除并且移到链表的头部,如果不存在,并且当前的cache满了,则将尾部删除,将新来的节点加入到链表的首部,否则直接加入练表中即可。

    get:如果当前的key在cache中,则将该节点从链表中移除并且添加带链表的首部并返回value,否则返回-1。

    代码给的是用hashmap和双链表完成的,因为当删除一个节点的时候,需要知道他的后记节点,虽然单链表也能做到这一点,但是如果要删除的节点是尾节点,那么就要知道他的前一个节点,这样的话就要便利整个链表,那么就会花o(n)的时间复杂度,虽然说当链表中有n个节点,那么(o(1)*(n-1) + o(n))/n这样平均的话时间复杂度是在o(1)的,但是也可以彻底做到时间复杂度是o(1)的,就用双链表,会将首位标记出来。

     
    struct Linklist
    {
        int key;
        int value;
        struct Linklist* pre;
        struct Linklist* next;
    };
    
    class LRUCache
    {
    private:
        int count;
        int size;
        struct Linklist* tail;
        struct Linklist* head;
        map<int,Linklist*>mp;
    public:
        LRUCache(int size)
        {
            this->size = size;
            this->tail = NULL;
            this->head = NULL;
            this->count = 0;
        }
        //如果该节点在map中存在,则删除当前的,并改变节点的值,将该节点放在双链表的表头
        //否则返回-1
        int get(int key)
        {
            if(head == NULL) return -1;
            map<int,Linklist*>::iterator it = mp.find(key);
            if(it == mp.end()) 
            {
                return -1;
            } 
            else 
            {
                Linklist *p = it->second;
                pushup(p);
            }
            return head->value;
        }
        //双链表删除节点 然后放在双链表的表头
        void pushup(Linklist* p)
        {
            if(this->count == 1) return ;
            if(p == this->head) return;
            if(p == this->tail) 
            {
                tail = p->pre;
            }
            p->pre->next = p->next;
            if(p->next != NULL)
                p->next->pre = p->pre;
    
            p->next = head;
            p->pre = NULL;
            head->pre = p;
            head = p;
        }
        //当前值,没有在cache中  则删除链表中最后一个节点&&map中删除,然后将访问的节点加在链表的表头
        //没有在cache中,则将尾删除  将新的元素入链表  并将元素加入到map中
        void  set(int key,int value)
        {
            if(head == NULL)
            {
                head = (Linklist *)malloc(sizeof(Linklist));
                head->value = value;
                head->key = key;
                head->pre = NULL;
                head->next = NULL;
                mp[key] = head;
                tail = head;
                this->count++;
            }
            else
            {
                map<int,Linklist*>::iterator it = mp.find(key);
                if(it == mp.end()) 
                {
                    if(size == count)
                    {
                        if(size == 1 && tail == head) //size == 1
                        {
                            mp.erase(head->key);
                            head->key = key;
                            head->value = value;
                            mp[head->key] = head;
                        }
                        else //
                        {
                            Linklist *p = tail;
                            tail->pre->next = p->next;
                            mp.erase(tail->key);
                            tail = tail->pre;
                            p->key = key;
                            p->value = value;
                            p->next = head;
                            head->pre = p;
                            head = p;
                            mp[head->key] = head;
    
                        }    
                    }
                    else
                    {
                        Linklist *p = (Linklist*)malloc(sizeof(Linklist));
                        p->value = value;
                        p->key = key;
                        p->next = head;
                        p->pre = NULL;
                        head->pre = p;
                        head = p;
                        mp[head->key] = head;
                        this->count++;
                    }
                }
                else
                {
                    Linklist *p = it->second;
                    p->value = value;
                    pushup(p);
                }
            }
        }
    };

    lala

  • 相关阅读:
    leetcode 29-> Divide Two Integers without using multiplication, division and mod operator
    ros topic 发布一次可能会接收不到数据
    python中的print()、str()和repr()的区别
    python 部分函数
    uiautomatorviewer错误 unable toconnect to adb
    pyqt 不规则形状窗口显示
    appium 计算器demo
    Spring 3.0 注解注入详解
    Spring Autowire自动装配
    restful 学习地址
  • 原文地址:https://www.cnblogs.com/chenyang920/p/5979076.html
Copyright © 2011-2022 走看看