数据结构设计

98 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

数据结构设计

1 算法就像搭乐高:带你手撸 LRU 算法

  • LRU 缓存(中等)

LRU 算法就是⼀种缓存淘汰策略,原理不难,但是⾯试中写出没有 bug 的算法⽐较有技巧,需要对数据结构进⾏层层抽象和拆解。

LRU 缓存淘汰算法就是⼀种常⽤策略。LRU 的全称是 Least Recently Used。

也就是说我们认为最近使⽤过的 数据应该是是「有⽤的」,很久都没⽤过的数据应该是⽆⽤的,内存满了就优先删那些很久没⽤过的数据。

LRU缓存 M146

题目描述

 请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。
 实现 LRUCache 类:
   
 - LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
 - int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
 - void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;
 如果不存在,则向缓存中插入该组 key-value。如果插入操作导致关键字数量超过 
 capacity ,则应该 逐出 最久未使用的关键字。
 
 函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
   
 // 示例    
 输入
 ["LRUCache""put""put""get""put""get""put""get""get""get"]
 [[2], [11], [22], [1], [33], [2], [44], [1], [3], [4]]
 输出
 [nullnullnull1null, -1null, -134]
 ​
 解释
 LRUCache lRUCache = new LRUCache(2);
 lRUCache.put(11); // 缓存是 {1=1}
 lRUCache.put(22); // 缓存是 {1=1, 2=2}
 lRUCache.get(1);    // 返回 1
 lRUCache.put(33); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
 lRUCache.get(2);    // 返回 -1 (未找到)
 lRUCache.put(44); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
 lRUCache.get(1);    // 返回 -1 (未找到)
 lRUCache.get(3);    // 返回 3
 lRUCache.get(4);    // 返回 4

解答

juejin.cn/post/710705…

2 算法就像搭乐高:带你手撸 LFU 算法

LFU 缓存机制 H460

LRU 算法的淘汰策略是 Least Recently Used,也就是每次淘汰那些最久没被使⽤的数据;

⽽ LFU 算法的淘汰策略是 Least Frequently Used,也就是每次淘汰那些使⽤次数最少的数据。

LRU 算法的核⼼数据结构是使⽤哈希链表 LinkedHashMap,⾸先借助链表的有序性使得链表元素维持插⼊ 顺序,同时借助哈希映射的快速访问能⼒使得我们可以在 O(1) 时间访问链表的任意元素。