146. LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get
和 写入数据 put
。
获取数据 get(key)
- 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value)
- 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。
进阶:
你是否可以在 O(1) 时间复杂度内完成这两种操作?
示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // 返回 1 cache.put(3, 3); // 该操作会使得密钥 2 作废 cache.get(2); // 返回 -1 (未找到) cache.put(4, 4); // 该操作会使得密钥 1 作废 cache.get(1); // 返回 -1 (未找到) cache.get(3); // 返回 3 cache.get(4); // 返回 4
// LRU缓存淘汰机制,淘汰最久没有被使用的 type LRUCache struct { m map[int]int nodeM map[int]*node size int l *linkedList } func Constructor(capacity int) LRUCache { lru := new(LRUCache) lru.init(capacity) return *lru } func (this *LRUCache) Get(key int) int { if _, ok := this.m[key]; !ok { return -1 } n := this.nodeM[key] this.l.delete(n) this.l.add(n) this.nodeM[key] = n return this.m[key] } func (this *LRUCache) Put(key int, value int) { if _, ok := this.m[key]; ok { n := this.nodeM[key] this.l.delete(n) this.l.add(n) this.nodeM[key] = n this.m[key] = value return } // 淘汰最旧的KEY if len(this.m) >= this.size { popKey := this.l.pop() delete(this.m, popKey) delete(this.nodeM, popKey) } // 添加新node newNode := &node{key: key} this.l.add(newNode) this.m[key] = value this.nodeM[key] = newNode } type node struct { key int pre *node next *node } type linkedList struct { head *node rear *node } func newLinkedList() *linkedList { return &linkedList{} } func (l *linkedList) add(n *node) { if l.head == nil { l.head = n l.rear = n return } l.rear.next = n n.pre = l.rear l.rear = n } func (l *linkedList) delete(n *node) { if l.head==l.rear{ l.head = nil l.rear = nil return } if n == l.head { l.head = n.next l.head.pre = nil return } if n == l.rear{ l.rear = n.pre l.rear.next = nil return } n.pre.next = n.next n.next.pre = n.pre } func (l *linkedList) pop() int { key := l.head.key if l.head==l.rear{ l.head = nil l.rear = nil return key } l.head = l.head.next l.head.pre = nil return key } func (c *LRUCache) init(size int) { c.m = make(map[int]int, size) c.nodeM = make(map[int]*node, size) c.size = size c.l = newLinkedList() }