LeetCode #146 - LRU Cache

题目描述:

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(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.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LRUCache cache = new LRUCache( 2 /* capacity */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // returns 1
cache.put(3, 3);    // evicts key 2
cache.get(2);       // returns -1 (not found)
cache.put(4, 4);    // evicts key 1
cache.get(1);       // returns -1 (not found)
cache.get(3);       // returns 3
cache.get(4);       // returns 4

实现一个LRU缓存,要求可以插入、查找,并且保证两种操作都是O(1)的时间复杂度。由于要求查找的时间复杂度为O(1),所以需要一个哈希表来存储每个元素和对应的位置,同时一旦查找、或者插入一个元素,这个元素就被更新为最新元素,而且如果元素超过LRU的容量就要把最近最不常用的元素删除,所以一个采用双向链表(STL中的list就是双向链表),最新元素放置于表头,最不常用元素放置于表尾,而且由于LRU缓存中一个元素的key表示搜索的键值,value表示对应的数值,那么双向链表中元素也应该是一个pair(key,value)。每次查找、插入一个元素,都要在O(1)的时间复杂度内把这个元素移动到表头,可以利用l.splice(l.begin(),l,it)实现,其中splice函数有三种形式:

①l.splice(iterator position,list<T,Allocator>& x ); 

②l.splice(iterator position, list<T,Allocator>& x,iterator i );

③l.splice(iterator position,list<T,Allocator>& x,iterator first, iterator last );

①表示将链表x全部插入到链表l中position之前;②表示将链表x中迭代器i指向的元素删除,并且插入到链表l中position之前;③表示将链表x中从迭代器first到last这一段链表删除,并且插入到链表l中position之前。list的splice函数时间复杂度为O(1),但是list的size函数是O(n)的时间复杂度。

class LRUCache {
public:
    LRUCache(int capacity) {
        len=capacity;
    }
    
    int get(int key) {
        if(hash.count(key)==0) return -1;
        list<pair<int,int>>::iterator it=hash[key];
        l.splice(l.begin(),l,it);
        return l.front().second;
    }
    
    void put(int key, int value) {
        if(hash.count(key)==0) 
        {
            l.push_front(pair<int,int>(key,value));
            hash[key]=l.begin();
        }
        else
        {
            list<pair<int,int>>::iterator it=hash[key];
            it->second=value;
            l.splice(l.begin(),l,it);
        }
        if(hash.size()>len)
        {
            int x=l.back().first;
            l.pop_back();
            hash.erase(x);
        }
    }

private:
    int len;
    list<pair<int,int>> l;
    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);
 */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值