题解 | #设计LFU缓存结构#[GO实现]
设计LFU缓存结构
https://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1
参考官方解题方案的GO代码实现,使用双哈希表和双向链表。
package main
import (
"container/list"
//"fmt"
"math"
)
type Node struct{
key,val,freq int
}
type LFUContainer struct{
capacity,size,min_freq int
freq_mp map[int]*list.List
mp map[int]*list.Element
}
func NewLFUContainer(c int) LFUContainer{
return LFUContainer{
capacity: c,
size: 0,
min_freq: math.MaxInt,
freq_mp: make(map[int]*list.List),
mp: make(map[int]*list.Element),
}
}
func (l *LFUContainer) update(e *list.Element,key ,value int){
//存下原节点
node:=e.Value.(Node)
freq:=node.freq
//从原频率map中删除该节点
l.freq_mp[freq].Remove(e)
//若当前频率没有对应节点,删除
if l.freq_mp[freq].Len()==0{
delete(l.freq_mp, freq)
//如果当前频率为最小,最小频率+1
if l.min_freq==freq{
l.min_freq++
}
}
if _,ok:=l.freq_mp[freq+1];!ok{
//更新频率的链表不存在
l.freq_mp[freq+1]=list.New()
}
//更新节点值
node.val=value
node.freq++
//插入链表表头
l.freq_mp[freq+1].PushFront(node)
//更新map
l.mp[key]=l.freq_mp[freq+1].Front()
}
func (l *LFUContainer) deleteLFU() {
//获取双向链表,元素,key
linkl:=l.freq_mp[l.min_freq]
e:=linkl.Back()
key:=e.Value.(Node).key
//删除链表尾部节点
linkl.Remove(e)
//如果链表为空,从频率map中删除
if linkl.Len()==0{
delete(l.freq_mp, l.min_freq)
}
//从map中移除key对应节点
delete(l.mp, key)
}
func (l *LFUContainer) set(key,value int) {
//检查key是否在l中存在
if e,ok:=l.mp[key];ok{
//存在,对应更新情况
l.update(e,key,value)
return
}
//插入情况
//判断是否达到最大容量
if l.size==l.capacity{
//执行删除LFU操作
l.deleteLFU()
}else{
l.size++
}
//设置最小频率
l.min_freq=1
node:=Node{key,value,1}
//在频率map中插入该节点
if _,ok:=l.freq_mp[1];!ok{
l.freq_mp[1]=list.New()
}
l.freq_mp[1].PushFront(node)
//在map中插入该节点
l.mp[key]=l.freq_mp[1].Front()
}
func (l *LFUContainer) get(key int) int{
res:=-1
//查找map
if e,ok:=l.mp[key];ok{
//获取值
res=e.Value.(Node).val
//更新频率
l.update(e, key, res)
}
return res
}
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* lfu design
* @param operators int整型二维数组 ops
* @param k int整型 the k
* @return int整型一维数组
*/
func LFU( operators [][]int , k int ) []int {
// write code here
container:=NewLFUContainer(k)
res:=make([]int,0)
for _,op:=range operators{
switch op[0]{
case 1:
container.set(op[1], op[2])
case 2:
res = append(res, container.get(op[1]))
}
}
return res
}
叮咚买菜工作强度 89人发布