6ES7216-2AD23-0xB8 从实现难度上来说,LFU 算法的难度大于 LRU 算法,因为 LRU 算法相当于把数据按照时间排序,这个需求借助链表很自然就能实现,你一直从链表头部加入元素的话,越靠近头部的元素就是新的数据,越靠近尾部的元素就是旧的数据,我们进行缓存淘汰的时候只要简单地将尾部的元素淘汰掉就行了。
而 LFU 算法相当于是淘汰访问频次最低的数据,如果访问频次最低的数据有多条,需要淘汰最旧的数据。把数据按照访问频次进行排序,而且频次还会不断变化,这可不容易实现。
所以说 LFU 算法要复杂很多,labuladong 进字节跳动的时候就被面试官问到了 LFU 算法。
话说回来,这种著名的算法的套路都是固定的,关键是由于逻辑较复杂,不容易写出漂亮且没有 bug 的代码。
那么本文 labuladong 就带你拆解 LFU 算法,自顶向下,逐步求精。
一、算法描述
要求你写一个类,接受一个capacIT(http://www.maoyihang.com/sell/l_25/)y参数,实现get和put方法:
class LFUCache { // 构造容量为 capacity 的缓存 public LFUCache(int capacity) {} // 在缓存中查询 key public int get(int key) {} // 将 key 和 val 存入缓存 public void put(int key, int val) {} }
get(key)方法会去缓存中查询键key,如果key存在,则返回key对应的val,否则返回 -1。
put(key, value)方法插入或修改缓存。如果key已存在,则将它对应的值改为val;如果key不存在,则插入键值对(key, val)。
当缓存达到容量capacity时,则应该在插入新的键值对之前,删除使用频次(后文用freq表示)最低的键值对。如果freq最低的键值对有多个,则删除其中最旧的那个。
// 构造一个容量为 2 的 LFU 缓存 LFUCache cache = new LFUCache(2); // 插入两对 (key, val),对应的 freq 为 1 cache.put(1, 10); cache.put(2, 20); // 查询 key 为 1 对应的 val // 返回 10,同时键 1 对应的 freq 变为 2 cache.get(1); // 容量已满,淘汰 freq 最小的键 2 // 插入键值对 (3, 30),对应的 freq 为 1 cache.put(3, 30); // 键 2 已经被淘汰删除,返回 -1 cache.get(2);
二、思路分析
一定先从最简单的开始,根据 LFU 算法的逻辑,我们先列举出算法执行过程中的几个显而易见的事实:
1、调用get(key)方法时,要返回该key对应的val。
2、只要用get或者put方法访问一次某个key,该key的freq就要加一。
3、如果在容量满了的时候进行插入,则需要将freq最小的key删除,如果最小的freq对应多个key,则删除其中最旧的那一个。
6ES7216-2AD23-0xB8REXROTH INDUCTION MOTOR MAD130B-0150-SA-S2-BH0-05-H1
REXROTH INDUCTION MOTOR MAD130B-0150-SA-S2-BH0-05-H1
Rexroth Brueninghaus Hydromatik A10VSO18DFR. NIB
A10VO60DFR1/52L-PUC61N00-SO547 PUMP BOSCH REXROTH
Rexroth Hydraulic Pump Press Comp Vane 1PV2V433/80RE16
1MR376A-B226 BOSCH REXROTH ROTOR *NEW*
REXROTH 3-842-999-904 USPP 3842999904
A10VO28DRG/31L-VSC62K52 PUMP BOSCH REXROTH
REXROTH 0-608-750-064 USPP 0608750064
Rexroth Servo Drive Unit, DKCXX.3-040-7 WARRANTY
New Rexroth Bosch Hydraulic Solenoid Valve, 4WRPE-10W
NEW REXROTH HNC100 VT-HNC100-2-30/P-1-00/000
NEW BOSCH REXROTH 36050000 MODULE LINEAR SLIDE
Rexroth Hydraulic Proportional Valve NEW #4WRE10EA64
REXROTH PISTON PUMP-AA10VSO71FED/30R
REXROTH SERVO VALVE NO: 3DS2EH 10-25/A2-140Z8M
REXROTH 3000PSI HYDRAULIC CYLINDERS 43MP-2318-PL-REV
Rexroth Indramat Indraview 40 Operator Panel CRT CNC
Rexroth Indramat MTS-R02 2-M2-B1-S4-N FWA MTSR0*-S01
Rexroth Hydraulic Bobcat drive motor, NEW
Rexroth Hydraulic Bobcat final drive planetary motor728