zoukankan      html  css  js  c++  java
  • leetcode LRU Cache

     题目链接。实现一个数据结构用于LRU,最近最少使用,O(1)插入和删除。关于LRU的基本知识可参考here

    先推荐JustDoIT的。

    下面是我自己实现的。

    class LRUCache{
    public:
    //146LRU Least Recently Used
        int LRUsize;
        struct LRUNode
        {
            int key;
            int value;
            LRUNode *pre, *next;
            LRUNode(int x, int y): key(x), value(y), pre(NULL), next(NULL){}
        };
        unordered_map<int, LRUNode *> LRUmap;
        LRUNode *head = NULL, *tail = NULL;
        
        LRUCache(int capacity)
        {
            LRUsize = capacity;
        }
    
        int get(int key)
        {
            if (LRUmap.count(key)) // if exists
            {
                if (head != LRUmap[key] && tail != LRUmap[key]) // 节点在中间
                {
                    LRUmap[key] -> pre -> next = LRUmap[key] -> next;
                    LRUmap[key] -> next -> pre = LRUmap[key] -> pre;
                    LRUmap[key] -> next = head;
                    head -> pre = LRUmap[key];
                    head = LRUmap[key];
                    head -> pre = NULL;
                }
                else if (head != LRUmap[key] && tail == LRUmap[key]) // 节点最后一个则放在头部即可
                {
                    tail = LRUmap[key] -> pre;
                    tail -> next = NULL;
                    LRUmap[key] -> pre = NULL;
                    head -> pre = LRUmap[key];
                    LRUmap[key] -> next = head;
                    head = LRUmap[key];
                }
                return LRUmap[key] -> value;
            }
            else
                return -1;
        }
    
        void set(int key, int value)
        {
            if (LRUmap.count(key))
            {
                LRUmap[key] -> value = value; // 一定要更新value
                if (head != LRUmap[key] && tail != LRUmap[key]) // 节点在中间
                {
                    LRUmap[key] -> pre -> next = LRUmap[key] -> next;
                    LRUmap[key] -> next -> pre = LRUmap[key] -> pre;
                    LRUmap[key] -> next = head;
                    head -> pre = LRUmap[key];
                    head = LRUmap[key];
                    head -> pre = NULL;
                }
                else if (head != LRUmap[key] && tail == LRUmap[key]) // 节点最后一个则放在头部即可
                {
                    tail = tail -> pre;
                    tail -> next = NULL;
                    LRUmap[key] -> pre = NULL;
                    head -> pre = LRUmap[key];
                    LRUmap[key] -> next = head;
                    head = LRUmap[key];
                }
            }
            else
            {
                LRUNode *tmp = new LRUNode(key, value);
                if (head == tail && head == NULL)
                {
                    head = tmp;
                    tail = tmp;
                    LRUmap[key] = head;
    
                }
                else if (LRUsize == LRUmap.size()) //注意可能容量只为1,满了记得删除
                {
                    tmp -> next = head;
                    head -> pre = tmp;
                    head = tmp;
                    LRUmap[key] = tmp;
                    LRUmap.erase(tail -> key);
                    tail = tail -> pre;
                    tail -> next = NULL;
     
                }
                else
                {
                    tmp -> next = head;
                    head -> pre = tmp;
                    head = tmp;
                    LRUmap[key] = tmp;
                }
            }
        }
    };
    View Code

    虽然AC了,不过我还在纠结不知道如何delete代码中new出来的内存。如果用java的话就不用delete了。但是看所有的leetcode提交的分布,c++普遍是速度最快的。

    貌似给出推荐的JustDOIT的也是没有delete的。

    然后我就找啊找。

    这一篇写的还不错。里面有原理解释,而且delete在析构中进行。用可用节点的数组存。或者是用原有的已经有的尾部来存新进入的点。这个想法不错。

    这题还是考察挺多的。出现频率高,有时间还是要好好消化。

  • 相关阅读:
    BZOJ 3144 [Hnoi2013]切糕
    一场比赛:20170707
    BZOJ 2815 [ZJOI2012]灾难
    BZOJ 1088 [SCOI2005]扫雷Mine
    BZOJ 1052 [HAOI2007]覆盖问题
    BZOJ 3505 [Cqoi2014]数三角形
    BZOJ 2957 楼房重建
    BZOJ 2654 tree
    丁酉年六月十一ACM模拟赛
    BZOJ 3438 小M的作物 & BZOJ 1877 [SDOI2009]晨跑
  • 原文地址:https://www.cnblogs.com/higerzhang/p/4163992.html
Copyright © 2011-2022 走看看