牛客网: BM100
题目: 设计实现LRU数据结构及算法
思路:
存储数据:
(1) 存储过(使用dict判断是否有值),使用makeRecent移至双端队列尾部;
(2) 未存储过,判断容量是否有余进行直接插入或删除最近最少使用结点再插入,涉及 deleteLRU(), addRecent(), deleteLRU使用双端队列removeFirst(), addRecent使有和双端队列addLast();
(3) 所需数据结构: Node存储key, val, pre, next;DoubleLinkedList存储head, tail Node, size;Solution存储capacity, dict, cache DoubleLinkedList。
代码:
// go
package main
type Node struct {
key, val int
pre, next *Node
}
func initNode(key, val int) *Node {
return &Node{
key: key,
val: val,
}
}
type DoubleLinkedList struct {
head, tail *Node
size int
}
func initDoubleLinkedList() *DoubleLinkedList {
dll := &DoubleLinkedList{
head: initNode(0, 0),
tail: initNode(0, 0),
size: 0,
}
dll.head.next = dll.tail
dll.tail.pre = dll.head
return dll
}
func (this *DoubleLinkedList) addLast(x *Node) {
x.pre = this.tail.pre
x.pre.next = x
x.next = this.tail
this.tail.pre = x
this.size++
}
func (this *DoubleLinkedList) remove(x *Node) {
x.pre.next = x.next
x.next.pre = x.pre
x.pre = nil
x.next = nil
this.size--
}
func (this *DoubleLinkedList) removeFirst() *Node {
if this.head.next == this.tail {
return nil
}
first := this.head.next
this.remove(first)
return first
}
type Solution struct {
// write code here
capacity int
dict map[int]*Node
cache *DoubleLinkedList
}
func Constructor(capacity int) Solution {
// write code here
lruCache := Solution{
capacity: capacity,
dict: map[int]*Node{},
cache: initDoubleLinkedList(),
}
return lruCache
}
func (this *Solution) makeRecent(key int) {
node := this.dict[key]
this.cache.remove(node)
this.cache.addLast(node)
}
func (this *Solution) addRecent(key, val int) {
node := &Node{
key: key,
val: val,
}
this.cache.addLast(node)
this.dict[key] = node
}
func (this *Solution) deleteKey(key int) {
node := this.dict[key]
this.cache.remove(node)
delete(this.dict, key)
}
func (this *Solution) deleteLRU() {
deleteLRU := this.cache.removeFirst()
delete(this.dict, deleteLRU.key)
}
func (this *Solution) get(key int) int {
// write code here
node, exist := this.dict[key]
if !exist {
return -1
}
this.makeRecent(key)
return node.val
}
func (this *Solution) set(key int, value int) {
// write code here
_, exist := this.dict[key]
if exist {
this.deleteKey(key)
this.addRecent(key, value)
} else {
if this.cache.size == this.capacity {
this.deleteLRU()
}
this.addRecent(key, value)
}
}
/**
* Your Solution object will be instantiated and called as such:
* solution := Constructor(capacity);
* output := solution.get(key);
* solution.set(key,value);
*/