题目链接
题目要求实现一个大小为Capacity,操作复杂度在O(1)的缓存列表,缓存规则:
1 放入数据,并且无论是覆盖放入还是新增的放入,均认为其是最新的数据
2 取得数据,并且若获取成功,则认为它是最新被取得过的数据
3 与规则中“最新”的概念相对应“最旧”概念,若放入数据时缓存列表超过上限Capacity,则需要移除一个“最旧”的数据
基本思路:LRU cache,使用一个双端链表+hashmap实现,“更新至最新”,“移除最旧”,“查找数据本身”均可通过常数级O(1)的时间复杂度实现
双端链表存储结构:数据本身+对应在hashmap中的key,其中key用来移除时快速寻找hashmap内位置
hashmap存储结构:key和数据在链表中元素的地址,用于O(1)的速度找到对应链表内的节点以进行后续操作
Runtime: 124 ms (beats 66.7%)
Memory Usage: 18.6 MB
type dataItem struct {
value int
key int
}
type LRUCache struct {
hashMap map[int]*list.Element
linkList *list.List
cap int
}
func Constructor(capacity int) LRUCache {
return LRUCache{make(map[int]*list.Element), list.New(), capacity}
}
func (this *LRUCache) Get(key int) int {
if v, ok := this.hashMap[key]; ok {
this.linkList.MoveToFront(v)
return v.Value.(*dataItem).value
}
return -1
}
func (this *LRUCache) Put(key int, value int) {
if v, ok := this.hashMap[key]; ok { // if exist update value & move to front
v.Value = &dataItem{value, key}
this.linkList.MoveToFront(v)
return
}
if this.linkList.Len() >= this.cap { // if overflow, remove back element
realEle := this.linkList.Back().Value.(*dataItem)
if realEle != nil {
if _, ok := this.hashMap[realEle.key]; ok {
delete(this.hashMap, realEle.key)
}
}
this.linkList.Remove(this.linkList.Back())
}
this.hashMap[key] = this.linkList.PushFront(&dataItem{value, key})
}
/**
* Your LRUCache object will be instantiated and called as such:
* obj := Constructor(capacity);
* param_1 := obj.Get(key);
* obj.Put(key,value);
*/