LRU C++ list+unordered_map实现,无需自己实现链表

设计LRU缓存结构

http://www.nowcoder.com/questionTerminal/e3769a5f49894d49b871c09cadd13a61

set 和 get的时候要先看在不在hash表中,在的话,从list和hash表中移除,再重新添加进list头部和hash表。另外添加元素的时候要注意超过容量就从list尾部淘汰元素,并删除hash表中对应的元素。
stl list的iterator是可以保存的,List添加删除元素不会导致其他iterator失效。因为iterator指向List中元素

#include <unordered_map>
#include <list>
#include <vector>
using namespace std;
struct Node
{
    Node(int k = 0, int v = 0) : key(k), val(v) {}
    int key;
    int val;
};
class Solution
{
public:
    /**
     * lru design
     * @param operators int整型vector<vector<>> the ops
     * @param k int整型 the k
     * @return int整型vector
     */
    vector<int> LRU(vector<vector<int>> &operators, int k)
    {
        // write code here
        cap = k;
        vector<int> ans;
        for (auto &input : operators)
        {
            if (input[0] == 1)
            {
                set(input[1], input[2]);
            }
            else
            {
                ans.push_back(get(input[1]));
            }
        }
        return ans;
    }
    //删除
    int remove(std::list<Node>::iterator &ite)
    {
        int key = ite->key;
        int val = ite->val;
        L.erase(ite);
        H.erase(key);
        return val;
    }
    // 添加
    void add(int key, int val)
    {
        L.push_front(Node(key, val));
        H[key] = L.begin();
        if (L.size() > cap)
        {
            auto last = L.end();
            --last;
            remove(last);
        }
    }
    void set(int x, int y)
    {
        auto ite = H.find(x);
        //已经存在,删除了再添加到头部
        if (ite != H.end())
        {
            remove(ite->second);
        }
        add(x, y);
    }
    int get(int x)
    {
        int val = 0;
        //已经存在,删除了再添加到头部
        auto ite = H.find(x);
        if (ite != H.end())
        {
            val = remove(ite->second);
            add(x, val);
            return val;
        }
        return -1;
    }

private:
    std::list<Node> L;
    std::unordered_map<int, std::list<Node>::iterator> H;
    int cap;
};
全部评论
这个删除后再重新插入的操作真好,我还实现如何调整他们的位置,有些细节挺麻烦的
3 回复 分享
发布于 2021-02-07 21:38
一直在思考查询元素时重新调整链表这一块怎么把复杂度降到O(1),因为从链表里找到指定元素并删除这个复杂度不是O(1)的所以一直没什么想法。看到这里豁然开朗
点赞 回复 分享
发布于 2021-10-26 16:08
好会用迭代器啊,根本没想过迭代器还可以做哈希表的值,学习了
点赞 回复 分享
发布于 2021-10-12 11:12
人家用的hash map,search就是O(1)啊
点赞 回复 分享
发布于 2021-08-01 23:02
这个想问一句如果要判断是否有某个K那岂不是一定要search?用search能O(1)吗
点赞 回复 分享
发布于 2021-07-23 10:50
用 List 不会变成 O(N) 吗
点赞 回复 分享
发布于 2021-07-18 19:11
太酷了!受教了!
点赞 回复 分享
发布于 2021-05-27 10:28
学习楼主对迭代器的使用
点赞 回复 分享
发布于 2021-04-24 19:29
remove 哪里为啥返回类型是int
点赞 回复 分享
发布于 2021-04-22 18:12
可以用一个队列实现双向链表的作用
点赞 回复 分享
发布于 2021-03-18 19:47

相关推荐

05-12 16:04
已编辑
江西财经大学 Java
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
49
8
分享

创作者周榜

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