是什么
LRU(Least Recently Used)
,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。
方法
LRUCache(capacity)
以正整数作为容量 capacity
初始化 LRU
缓存
get(key)
如果关键字 key
存在于缓存中,则返回关键字的值,否则返回 -1
。
put(key, value)
如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」
。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
leetcode 习题 用于验证
array + hash 版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
var LRUCache = function (capacity) { this.capacity = capacity this.keys = [] this.values = {} }
LRUCache.prototype.get = function (key) { const value = this.values[key] if (value === undefined) return -1 this.update(key) return value }
LRUCache.prototype.update = function (key) { for (let i = 0; i < this.keys.length; i++) { if (key === this.keys[i]) { for (let j = i; j >= 1; j--) { this.keys[j] = this.keys[j - 1] } this.keys[0] = key break } } }
LRUCache.prototype.put = function (key, value) { const val = this.values[key] this.values[key] = value if (val !== undefined) { this.update(key) } else { if (this.keys.length >= this.capacity) { delete this.values[this.keys.pop()] } this.keys.unshift(key) } }
|
虽然通过,但是效率并不高
采用双向链表优化
更新过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
function Node(k, v, l, r) { this.l = l this.r = r this.k = k this.v = v }
var LRUCache = function (capacity) { this.size = capacity this.map = new Map() this.head = new Node(-1, -1) this.tail = new Node(-1, -1) this.head.r = this.tail this.tail.l = this.head }
LRUCache.prototype.get = function (key) { const node = this.map.get(key) if (!node) return -1 this.update(node) return node.v }
LRUCache.prototype.update = function (node) { this.delete(node) node.r = this.head.r node.l = this.head this.head.r.l = node this.head.r = node }
LRUCache.prototype.delete = function (node) { if (node.l) { let l = node.l l.r = node.r node.r.l = l } }
LRUCache.prototype.put = function (key, value) { const node = this.map.get(key) || new Node(key, value) node.v = value this.map.set(key, node) this.update(node) if (this.map.size > this.size) { let del = this.tail.l this.map.delete(del.k) this.delete(del) } }
|
源码地址