LeetCode 146. LRU 缓存机制

题目描述

146. LRU 缓存机制

解法一:哈希表+双向链表(C++)

我们自己实现的双向链表+ std::unordered_map,注意这里unordered_map存的是关键字和关键字节点

class LRUCache {
    class DLinkNode{
        public:int key;
        int value;
        DLinkNode* prev;
        DLinkNode* next;
    };

    int addnode(DLinkNode* node)
    {
        node->next = head->next;
        head->next = node;
        node->prev = head;
        node->next->prev = node;
        return 0;
    }

    int removenode(DLinkNode* node)
    {
        node->prev->next = node->next;
        node->next->prev = node->prev;
        return node->key;
    }

    int movetohead(DLinkNode* node)
    {
        removenode(node);
        addnode(node);
        return 0;
    }

private:
    unordered_map<int, DLinkNode*> cache;
    int size;
    int capacity;
    DLinkNode* head, *tail;

public:
    LRUCache(int capacity) {
        head = new DLinkNode();
        tail = new DLinkNode();
        head->next = tail;
        tail->prev = head;
        this->capacity = capacity;
        size = 0;

    }
    
    int get(int key) {
        unordered_map<int, DLinkNode*>::iterator it = cache.find(key);
        if(it==cache.end()) return -1;
        movetohead(it->second);
        return it->second->value;
    }
    
    void put(int key, int value) {
        unordered_map<int, DLinkNode*>::iterator it = cache.find(key);
        if(it==cache.end())
        {
            DLinkNode* node = new DLinkNode();
            node->value = value;
            node->key = key;
            addnode(node);

            cache.insert(make_pair(key, node));
            size++;
            if(size>capacity)
            {
                int key = removenode(tail->prev);
                cache.erase(key);
                size--;
            }
        }
        else 
        {
            it->second->value = value;
            movetohead(it->second);
        }
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

下面一个代码是用std::list + std::unordered_map,注意这里的unordered_map是面存的是关键字和关键字的位置

class LRUCache {
public:
    LRUCache(int capacity):capacity_(capacity){

    }
    
    int get(int key) {
        if(hash_.find(key)==hash_.end()) return -1;
        else
        {
            // 把刚访问的(key, value)放在链表头
            int value = hash_[key]->second;
            ls_.erase(hash_[key]);
            ls_.push_front(make_pair(key, value));
            // 更新(key, value)在链表中的位置
            hash_[key] = ls_.begin();
            return value;
        }
    }
    
    void put(int key, int value) {
        if(hash_.find(key)!=hash_.end()) ls_.erase(hash_[key]);
        if(ls_.size()>=capacity_)
        {
            hash_.erase(ls_.back().first);
            ls_.pop_back();
        }
        ls_.push_front(make_pair(key, value));
        hash_[key] = ls_.begin();
    }

private:
    int capacity_;
    list<pair<int, int>> ls_;
    unordered_map<int, list<pair<int, int>>::iterator> hash_;
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

解法二:OrderedDict (Python)

有一种叫做有序字典的数据结构,综合了哈希表和链表,在 Python 中为 OrderedDict,详细可参阅:OrderedDict

from collections import OrderedDict

class LRUCache(OrderedDict):

    def __init__(self, capacity: int):
        self.capacity = capacity


    def get(self, key: int) -> int:
        if key not in self: return -1 
        self.move_to_end(key)
        return self[key]


    def put(self, key: int, value: int) -> None:
        if key in self: self.move_to_end(key)
        self[key] = value
        if len(self) > self.capacity: self.popitem(last=False)




# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值