题解 | #LRU Cache#

LRU Cache

https://www.nowcoder.com/practice/3da4aeb1c76042f2bc70dbcb94513338

#include <iostream>
#include <map>
using namespace std;

class ListNode {
public:
    int val;
    int key;
    ListNode* pre;
    ListNode* next;
    ListNode(int ky, int va) :key(ky), val(va), pre(nullptr), next(nullptr) {}
    ListNode() :pre(nullptr), next(nullptr), key(-1), val(-1){}
};

class LRU {
private:
    map<int, int> kvMap;
    ListNode* head;
    ListNode* end;
    int size;
public:
    LRU() :head(nullptr),end(nullptr), size(0) {}
    LRU(int size) :head(nullptr), end(nullptr), size(size) {}
    int get(int key) {
        if (kvMap.find(key) == kvMap.end()) {
            return -1;
        }
        ListNode* p = head;
        ListNode* pre = nullptr;
        while (p) {
            if (p->key == key) {
                if (p == head && p->next) {
                    head = p->next;
                }
                else if ((p == head && !p->next )||(p == end)) {
                    return kvMap[key];
                }
                if (pre) {
                    pre->next = p->next;
                }
                if (p->next) {
                    p->next->pre = pre;
                }
                p->pre = end;
                end->next = p;
                p->next = nullptr;
                end = p;
            }
            pre = p;
            p = p->next;
        }
        return kvMap[key];
    }

    void put(int key, int val) {
        if (size == 0) {
            return;
        }
        if (kvMap.find(key) != kvMap.end()) {
            kvMap[key] = val;
            ListNode* p = head;
            while (p) {
                if (p->key == key) {
                    p->val = val;
                    return;
                }
                p = p->next;
            }
            return;
        }
        if (kvMap.size() + 1 > size) {
            ListNode* old = head;
            kvMap.erase(old->key);
            head = head->next;
            if (end == old) {
                end = nullptr;
            }
            delete old;
            
        }
        kvMap[key] = val;
        if (head == nullptr) {
            head = new ListNode(key, val);
        }
        else if (end == nullptr) {
            end = new ListNode(key, val);
            head->next = end;
            end->pre = head;
        }
        else {
            end->next = new ListNode(key, val);
            end->next->pre = end;
            end = end->next;
            
        }
    }

};

int main() {
    int size;
    cin >> size;
    LRU lru(size);
    char x;
    int k, v;
    while (cin >> x) {
        if (x == 'p') {
            cin >> k >> v;
            lru.put(k, v);
        } else {
            cin >> k;
            cout << lru.get(k) << endl;
        }
    }
}
// 64 位输出请用 printf("%lld")

写的不是很好,主要就是一个双向链表的更新,好像hash表也是不必要的

全部评论

相关推荐

11-06 12:53
吉林大学 Java
如题,ip属地末九,计算机科班大三本科生。想找一段寒假实习,也是第一次找实习。&nbsp;从大二暑假7月开始准备Java后端,前期有点磨叽,导致现在手忙脚乱。目前第二个项目黑马点评快写完了,第一个项目是苍穹外卖(两个项目都是烂大街的,这就很头大)。算法题在lc上从大二至今陆续刷了将近六百题,hot100已过一遍,面试150目前刷了一半。八股刚看了不到一周,想请教一下各位牛友,这一版简历哪些地方需要继续改进,接着优化?&nbsp;同时,是现在立即开始投递,边投边背八股,完善项目。还是说八股再背个小半个月再开始投递比较好一点,我现在担心的是到了这个月下旬或者12月再开始投递简历面试会有点晚,听同学说到年底hc数量会大...
mikeu04:简历顶部留名字即可,你写“后端开发实习生-Java”就是把自己的方向限制死了。我建议把这揉在个人简介里,说你对后端开发充满热情就行。性别出生年份以及微信号不是必须的。 把个人简介从教育背景里拿出来,第一个写。你的个人简介有点太泛了。把“爱好中长跑”去了,加点数字(“拥有xxx年的xxx经历”),加点你最熟的几个语言或技术栈。和别人的简介区分开来。 专业技能放项目经历前面。面试官一般会优先看这个再往下看你做了什么项目来考察你是否具备这些技能。实习我不是很清楚,但像Redis, JVM, 消息模型,计算机网络这些属于基本知识。你如果了解GCP, AWS, Docker 这些实际生产工具就可以把八股知识换掉。 项目简介可以和工作内容揉在一起。项目简介还是太长了,就一句话,“开发了一个基于【1,2个主要框架】为【目标客户群体】的【产品类型】, 实现了【产品价值】”。产品价值不是功能。比如一个在线计算器,它的功能是算数,但它的价值可以是让人在没带计算器的情况下算数(可访问性)或比手算效率提升了80%。工作内容多加点数字,你这个产品有多少人用了?浏览量是多少?技术上xxx性能提升了多少%?(实在想不出来就丢给deepseek :) 11 月理论上秋招已经结束了。八股是背不完的。无脑投,刷笔试,中了面试邀请就突击面经八股,没问题的。
大厂面试问八股多还是项目...
点赞 评论 收藏
分享
Aurora23:属于挂一半,暂时进池子了,隔一段时间没有其他组捞的话就彻底结束了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务