范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

程序员面试金典面试题16。25。LRU缓存

  题目难度: 中等
  原题链接  [1]
  今天继续更新程序员面试金典系列, 大家在公众号   算法精选   里回复  面试金典   就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述
  设计和构建一个"最近最少使用"缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存被填满时,它应该删除最近最少使用的项目。
  它应该支持以下操作: 获取数据 get 和 写入数据 put 。 获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。 写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。 示例:LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );  cache.put(1, 1); cache.put(2, 2); cache.get(1);       // 返回  1 cache.put(3, 3);    // 该操作会使得密钥 2 作废 cache.get(2);       // 返回 -1 (未找到) cache.put(4, 4);    // 该操作会使得密钥 1 作废 cache.get(1);       // 返回 -1 (未找到) cache.get(3);       // 返回  3 cache.get(4);       // 返回  4 题目思考相当经典的一道题目, 要使得更新和查询都是 O(1)复杂度, 你想到了哪些数据结构组合能做到? 解决方案思路先设计需要使用的数据结构 根据 LRU 描述, 我们至少需要一个数据结构来存节点的新旧程度, 新的可以放一边, 老的放另一边, 这自然就是双向链表但是问题是链表虽然更新很快, 是 O(1), 但如何快速通过一个 key 查到对应的节点呢?很容易想到字典/hash 可以做到 O(1)查询, 然后要做的就是把这两个数据结构结合起来: 双向链表存节点的先后顺序, head 最新, tail 最老字典存 key=>节点的映射, 方便快速根据 key 定位到节点 接下来就是写具体的逻辑了, 这里一共有 3 种操作: get 和 put 已经存在的节点: 把已经存在的节点重新放在头部put 新的节点: 把新的节点放在头部删除最老的节点: 如果加入新节点后超过 capacity, 那么需要把最老的 tail 给去掉 逻辑优化 根据第 2 步中分析的 3 种操作, 我们可以直接写出每一种操作对应的代码, 但是里面会有很多重复的部分, 比如放在头部的操作在 2.1 和 2.2 都有, 而删除节点的操作则在 2.1 和 2.3 都有所以我们完全可以将这两部分操作提取出来一个是 add 节点操作, 把节点放到头部, 并更新连接关系和字典一个是 remove 节点操作, 删除某个节点, 并更新连接关系和字典 最后就是具体的代码部分了, 下面代码对每步操作都有详细的注释, 希望可以帮助大家更好理解 复杂度时间复杂度 O(1): 链表保证更新是 O(1), 字典保证查询是 O(1) 空间复杂度 O(C): C 是 capacity, 字典需要存这么多个 kv, 所以是 O(C) 代码class LRUCache:     class BiNode:         def __init__(self, k, v):             self.key = k             self.val = v             self.pre = None             self.nex = None      def __init__(self, capacity: int):         # 双向链表+字典         # 双向链表存节点的先后顺序, head最新, tail最老         # 字典方便快速根据key定位到节点         # 注意链表节点需要存key和value, 存key的目的是用于字典的检索         # 两者结合就能保证更新和查询的时间复杂度都是O(1), 链表保证更新是O(1), 字典保证查询是O(1)         # 注意提取新增和移除节点的逻辑, 方便复用, 简化代码         self.head = None         self.tail = None         self.kv = {}         self.capacity = capacity      def add(self, node):         # 将节点加到链表头         # 先操作字典         self.kv[node.key] = node         # 再更新节点连接关系和头尾         if not self.head:             # 没有head, 说明当前链表为空, 直接head和tail都设为node即可             self.head = self.tail = node         else:             # 更新新的head以及它与老head的连接关系             node.nex = self.head             self.head.pre = node             self.head = node      def remove(self, node):         # 移除某个节点         # 先操作字典         if node.key in self.kv:             del self.kv[node.key]         # 再更新节点连接关系和头尾         # 更新左右邻居的连接关系         pre, nex = node.pre, node.nex         # 注意当前节点的pre和nex都要重置为None         node.pre = node.nex = None         if pre:             pre.nex = nex         if nex:             nex.pre = pre         # 更新新的头尾         if node == self.head:             self.head = nex         if node == self.tail:             self.tail = pre      def get(self, key: int) -> int:         # 注意get操作也需要将node更新到链表头         if key in self.kv:             node = self.kv[key]             # 先把node从当前位置移除, 然后加入头部             self.remove(node)             self.add(node)             return node.val         return -1      def put(self, key: int, value: int) -> None:         if self.capacity <= 0:             # 如果capacity是0, 直接无法添加             return         if key in self.kv:             # 如果当前key存在的话, 先移除它             self.remove(self.kv[key])         elif len(self.kv) == self.capacity:             # 注意如果当前已经达到capacity的话先移除tail             self.remove(self.tail)         # 加入新节点到头部         newNode = self.BiNode(key, value)         self.add(newNode) 参考资料
  [1]
  原题链接: https://leetcode-cn.com/problems/lru-cache-lcci/

特斯拉CEO马斯克,教贝索斯造车,为Rivian汽车提建议特斯拉CEO马斯克向电动汽车初创公司Rivian提供了一些关于制造工作的宝贵建议,这些建议可能有助于公司的长寿。在有报道称Rivian的第二家美国汽车工厂可能会落户德克萨斯州沃思堡被投资人像小学生一样训话的雷军,却默默投资了400多家公司8月10日,雷军年度演讲暨小米秋季发布会在线上如期进行。在演讲中,演讲中他提到2018年7月9号,小米IPO破发,当时,大家全懵了。仪式结束后有很多媒体堵在门口,谁也不愿意面对尴尬didoR6智能手环送给准大学生表妹的礼物这个暑假正是高三学子们扎堆办升大学宴的日子,这不,表妹考上了大学,非要我去参加。除了要准备个大红包,礼物自然也不能少。于是,我决定给她送一个智能手环,希望她在大学期间做好时间的管理老年人听损除了戴助听器外,还有其他方法吗?大多数老年人的听力损失都是属于感音神经性的,随着年龄的不断增长,耳蜗老化,耳蜗内毛细胞受损,最好的办法就是助听器干预。随着老龄要看是什么原因引起的听损,如果是中耳炎,可以通过治疗,一加66T推送OxygenOS11系统稳定版更新外媒MSPoweruser报道,在一加6和6T上测试了一个多月的OxygenOS11更新后,一加终于开始将OxygenOS11稳定版更新推送到这两款近四年的骁龙845智能手机上。正荣耀CEO赵明不看好屏下摄像头的新技术?称影像效果不可接受手机行业竞争激烈,所以为了更好的让自家手机占有优势地位,很多手机厂商都会采用最新的技术,比如屏下摄像头技术开始爆发了,目前已有中兴Axon30小米MIX4和三星ZFold3等手机用荣耀也开始收割韭菜了?荣耀magic3值得购买吗?荣耀magic3已经发布了,对于这款手机的评价,我只能用两个字来形容了,那就是无语。我一般来说不会去喷手机,但对于这款手机我还是想好好喷下,你们帮忙分析我说的对不对。在性能这方面,适合玩游戏的旗舰手机有哪些?专业配置,为游戏而生现代人使用手机,除了聊天追剧聊电话刷微信以外,打游戏也是不少人在通勤闲暇时刻的嗜好。不过,若是手机规格不够强悍,那打起游戏来恐怕只会卡卡,若再加上手机本身已经老旧,那更是会慢到令人适合学生党的千元机,看看你在用吗今天介绍两款1000元左右的机型,堪称千元机皇第一款,红米note95G手机这款手机采用的了一块6。53英寸的全高清小孔全面屏,颜值相当高。主cpu选用了一块联发科的中端处理器天玑滴滴出大招,花小猪20号免佣模式开启,来对抗众多平台的围剿在滴滴被调查这段时间,滴滴终于憋出大招了,花小猪免佣金,具体免佣到几号官方还未给出最新答复!滴滴花小猪在8。20号推出免佣模式,单单免佣金,每单只收取1。5元信息费,还不限制时间段德国肖特为三星GalaxyZ系列新机供应大部分UTG屏幕玻璃IT之家8月13日消息根据外媒TheElec消息,德国肖特公司赢得了与美国康宁的竞争,为三星新发布的GalaxyZFlip3Fold3两款折叠屏新机供应大部分UTG超薄玻璃,用于折
win10专业版玩游戏花屏的具体解决方法有不少深度技术的小伙伴,都喜欢玩游戏的,但是一位安装win10专业版的用户却遇到玩游戏花屏的问题,也许有不少用户都遇到过这个问题吧,下面深度系统小编来分享一下相关的解决方法。方法如windows7玩魔兽争霸3无法进入闪退修复的方法有深度技术windows7中文版系统用户,喜欢在电脑中玩魔兽争霸3的游戏,可是安装好游戏以后却发现无法进入游戏,一直卡在装载中,或者出现闪退的问题,为此,深度系统小编给大家分享一下已经死去的KTV上一次去KTV是什么时候?当朋友问起的时候,我的大脑使劲搜索了一下回忆,发现上一次真正意义上去KTV还是大学毕业前班里同学聚会。那时候正值乐坛快速发展的时候,男有周王林陶,女有孙莫14岁奥运冠军全红婵爆红后,最不愿看到的一幕还是发生了作者在风来源在风快跑(IDcrazyingstory)这几天,14岁的全红婵,刷屏全网。这个女孩到底有多牛逼呢?她在决赛中跳了五次,其中三次拿了满分,当场打破了世界记录!这个瞬间被霍尊官宣退圈,父亲火风力证儿子清白来源文翼说(IDwenyishuo66)古风男神霍尊和舞蹈演员陈露的事,已经发酵好几天了。8日,陈露晒出自己和霍尊的亲密照并霍尊,疑似公开两人的情侣关系,却未等到霍尊本人回应。10恶魔在枕边死的是我老婆啊,得多骗点钱当我们在说一个人不择手段的时候,很多时候他并不是不择手段,只是花样比较多,在规则的边缘反复试探。真正的不择手段是骗保者为了金钱,可以去杀害自己的亲人,并且内心毫无愧疚。在他们眼里,乔家的儿女热播为什么好人,却都难有好婚姻?公众号关注诺好杂谈了解人生百态最近口碑爆表的剧,非乔家的儿女莫属。(图片来自网络侵删)乔家的几个孩子,从很小的时候就丧母,而父亲乔祖望却并没有像一个称职的父亲的那样,担负起儿女的抚后真相时代的我们,理性看待西安地铁拖拽事件公众号关注诺好杂谈了解人生百态前几天西安地铁保安拖拽女乘客事件引发舆论热议。如今热度散去,我们再回过头看这件事,是否会不一样呢?时间退回到8月30日,在西安地铁3号线上,一名女子与重提冠姓权女性与姓氏的争端公众号关注诺好杂谈了解人生百态大概一年前,某天我和母亲走在路上,遇到一个不怎么熟悉的人问路,那人顺口问了一句你姓什么?母亲说姓陈。这件事让我大发雷霆,因为,陈是父亲的姓氏。写到这里流畅运行PS,还可以玩英雄联盟惠普星14笔记本体验让你用一个词去形容惠普星14这款笔记本电脑,你会用什么样的词呢?如果让我来选,我可能会用灵动去形容它。我们在选笔记本时可能会遇到这样的问题,选性能强悍的游戏本,大多太过于笨重不能随电脑文件太多放不下?这款希捷新睿翼移动硬盘值得推荐我为什么要入手希捷新睿翼因为要经常外出码字,所以前段时间入手了MacbookAir,这款笔记本性能满足日常需要而且还轻巧,整体我比较满意。但作为一个经常要剪辑视频的工作者,使用Ma