题目简述:
设计数据结构,模拟 LRU(Least Recently Used),且要实现两个时间复杂度为 O(1)
的方法:
set(key, value)
:往 LRU 结构中插入记录key -> value
get(key)
:从 LRU 结构中获取key
对应的value
,若无该记录,返回-1
每当使用了这两个方法之一,这个 key
记录就会变成当前最常用的记录;限制了存储容量 k
,当保存的记录条数超过 k
时,就将其中最不常用的记录删除。
定义了两个操作 1
和 2
,1
代表了set
操作,2
代表了get
操作,
输入:[[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3
输出:[1,-1]
说明:输入代表了一系列操作,[1,1,1]
中第一个数字为操作,后两个数字为 key
和 value
,[2, 1]
第一个数字代表操作,第二个数字代表 key
,最后一个数字 3
代表这个结构的容量。
解法1:queue + map
定义一个 queue
和一个 map
。
queue
是一个队列,用于存储结构中现存的 key
,队列中 key
的顺序就表示了这条记录的常用程度,处于队尾的最常用,处于队首的最不常用。
当存储容量仍有剩时,往队尾中加入这个 key
,当超出了存储容量时,从队首移除这个 key
。当发生了get
或 set
操作时,从这个队列中查找是否有对应记录,若有,将其移至队尾。
map
则用于存储记录的键值对,每当插入一个 key,value
时,先查找是否存在 key
对应的记录,若存在,则更新这条记录的 value
,否则新增一条记录。
这种方法逻辑上可行,但在进行 set
或 get
操作时,若已存在该记录,则需要将其移至队尾,这样的操作在 O(1)
的时间内是无法完成 的。
JS 代码如下:
/**
* lru design
* @param operators int整型二维数组 the ops
* @param k int整型 the k
* @return int整型一维数组
*/
function LRU( operators , k ) {
let map = new Map();
let list = [];
let ans = [];
for (let data of operators) {
let op = data[0];
let key = data[1], value = data[2];
if (op === 1) {
if (list.length >= k) {
list.shift()