運用你所掌握的數據結構,設計和實現一個 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() }