美文网首页
146. LRU Cache

146. LRU Cache

作者: jluemmmm | 来源:发表于2021-01-23 17:00 被阅读0次

LRU(最近最少使用)缓存机制。
实现 LRU 类:

  • 以正整数作为容量 capacity 初始化缓存
  • get(key) 方法,如果关键字key 存在于缓存中,返回关键字的值,否则返回 -1
  • put(key, value) 如果关键字已经存在,变更其数据值,如果关键字不存在,插入该组关键字-值,当缓存容量达到上限时,在写入新数据之前删除最久未使用的数据值,为新的数据值留出空间。

用 O(1)时间复杂度完成这些操作。

map 实现

设置缓存,Least Recently Used (LRU) cach,利用map实现,每次get/put之前先移除之前的设置,最近使用的元素在最后,超出容量时通过map.keys().next().value 删除

利用map的特性,map.keys() 返回的是一个迭代器,返回的顺序按照set 的顺序,因此可以通过 map.keys().next().value 获得最先被 set 的数据。

  • Runtime: 184 ms, faster than 92.78%
  • Runtime: 184 ms, faster than 92.78%
/**
 * @param {number} capacity
 */
var LRUCache = function(capacity) {
    this.cache = new Map()
    this.capacity = capacity
};

/** 
 * @param {number} key
 * @return {number}
 */
LRUCache.prototype.get = function(key) {
    if(this.cache.has(key)) {
        const value = this.cache.get(key)
        this.cache.delete(key)
        this.cache.set(key, value)
        return value
    }
    return -1
};

/** 
 * @param {number} key 
 * @param {number} value
 * @return {void}
 */
LRUCache.prototype.put = function(key, value) {
    if(this.cache.has(key)) {
        this.cache.delete(key)
        this.cache.set(key, value)
    } else {
        if(this.cache.size >= this.capacity) {
            this.cache.delete(this.cache.keys().next().value)
        } 
        this.cache.set(key, value)
    }
};

/** 
 * Your LRUCache object will be instantiated and called as such:
 * var obj = new LRUCache(capacity)
 * var param_1 = obj.get(key)
 * obj.put(key,value)
 */

哈希表 + 双向链表

要让 put 和 get 方法的时间复杂度为 O(1),需要查找快,插入快,删除快,有顺序之分。符合上面条件的数据结构:哈希表,查找快,数据无固定顺序;链表有顺序之分,插入删除快,查找慢。将二者进行结合。Map方法实现的便捷性在于map的插入是有顺序的。

为什么需要双向链表,因为对于删除操作,删除一个节点不仅需要该节点本身的指针,还需要操作前驱节点的指针,双向链表可以支持直接查找前驱节点,保证操作的时间复杂度为O(1)。

哈希表中已经存了key,为什么双向链表中还要存储键值对,当缓存容量满了的时候,不仅需要删除 双向链表中的节点,还要把 哈希表中映射到该节点的key同时删除,这个key 只能由链表中的节点得到。

  • Runtime: 228 ms, faster than 36.29%
  • Memory Usage: 52 MB, less than 37.76%
class Node {
    constructor(key, val) {
        this.key = key
        this.val = val
    }
}

class DoubleLinkedListNode {
    constructor() {
        this.head = new Node(0, 0)
        this.tail = new Node(0, 0)
        this.head.next = this.tail
        this.tail.prev = this.head
        this.size = 0
    }
    
    remove(node) { 
        node.next.prev = node.prev
        node.prev.next = node.next
        node.next = null
        node.prev = null
        this.size--
    }
    
    addHead(node) {
        node.next = this.head.next
        node.prev = this.head
        this.head.next.prev = node
        this.head.next = node
        this.size++
    }
    
    removeTail() {
        if(this.tail.prev === null) return null
        const tail = this.tail.prev
        this.remove(tail)
        return tail
    }
    getSize() {
        return this.size
    }
}

var LRUCache = function(capacity) {
    this.hashMap = {}
    this.capacity = capacity
    this.link = new DoubleLinkedListNode()
};

LRUCache.prototype.get = function(key) {
    if(!(key in this.hashMap)) return -1
    const node = this.hashMap[key]
    this.put(key, node.val)
    return node.val
};


LRUCache.prototype.put = function(key, value) {
    if(key in this.hashMap) {
        const node = this.hashMap[key]
        this.link.remove(node)
        node.val = value
        this.link.addHead(node)
    } else {
        const node = new Node(key, value)
        this.hashMap[key] = node
        if(this.link.getSize() >= this.capacity) {
            const tail = this.link.removeTail()
            delete this.hashMap[tail.key]
        }
        this.link.addHead(node)
    }
};

相关文章

  • 146. LRU Cache

    146. LRU Cache

  • 2019-01-13

    LeetCode 146. LRU Cache Description Design and implement ...

  • LeetCode 146-150

    146. LRU缓存机制[https://leetcode-cn.com/problems/lru-cache/]...

  • LRU(leetcode.146)

    146. LRU 缓存机制[https://leetcode-cn.com/problems/lru-cache/...

  • 146. LRU 缓存

    146. LRU 缓存[https://leetcode.cn/problems/lru-cache/] 请你设计...

  • 146. LRU 缓存

    题目地址(146. LRU 缓存) https://leetcode.cn/problems/lru-cache/...

  • 146. LRU Cache

    使用 LinkedHashMap,这样 Key 的 order 就是添加进 Map 的顺序。逻辑如下: 代码如下:...

  • 146. LRU Cache

    Design and implement a data structure for Least Recently ...

  • 146. LRU Cache

    这题不难,就是要理解清楚,然后注意一下各种细节就好。

  • 146. LRU Cache

    题目描述:为最近最少使用缓存LRU Cache设计数据结构,它支持两个操作:get和put。 get(key):如...

网友评论

      本文标题:146. LRU Cache

      本文链接:https://www.haomeiwen.com/subject/yajuzktx.html