题解 | #设计LRU缓存结构#

设计LRU缓存结构

https://www.nowcoder.com/practice/5dfded165916435d9defb053c63f1e84

package main

// 手动实现LRU&时间复杂度为1.
// 双端有序列表 + hashMap.
// get & set -> 时间复杂度为1; -> HashMap
// set的时候需要弹出最不常用的元素; -> 根据元素的顺序排列
// 每次get;set都用把元素放到最高优先级;放到队列末尾
//调试代码难;做好把拆分方法的;尽量复用性高
type dataNode struct {
	Key  int
	Val  int
	pre  *dataNode
	next *dataNode
}
type Solution struct {
	// write code here
	HashStorage map[int]*dataNode //节点值指向具体的节点
	Cap         int               //容量
	Head        *dataNode         //双端列表的头
	Tail        *dataNode         //双端列表的尾
}

func Constructor(capacity int) Solution {
	// write code here
	return Solution{
		HashStorage: make(map[int]*dataNode),
		Cap:         capacity,
		Head:        nil,
		Tail:        nil,
	}
}

func (this *Solution) get(key int) int {
	// write code here
	node, ok := this.HashStorage[key]
	if !ok {
		return -1
	}

	//添加到队列的末尾
	this.moveNodeToTheEnd(node)
	return node.Val
}
func (this *Solution) moveNodeToTheEnd(node *dataNode) {
	if this.Tail == node {
		return
	}
	//前后节点建立链接;保证有效
	//从原先的位置删除
	this.deleteFromList(node)

	//放到后面
	this.addNodeToEnd(node)
}

func (this *Solution) deleteFromList(node *dataNode) {
	//唯一元素
	if this.Head == node && this.Tail == node {
		this.Head = nil
		this.Tail = nil
		return
	}
	//队尾?
	if this.Tail == node {
		if this.Tail.pre != nil {
			this.Tail.pre.next = nil
		}
		this.Tail = this.Tail.pre
		return
	}
	//队首
	if this.Head == node {
		if this.Head.next != nil {
			this.Head.next.pre = nil
		}
		this.Head = this.Head.next
		return
	}
	//队中
	node.pre.next, node.next.pre = node.next, node.pre
}

// 队尾添加元素
func (this *Solution) addNodeToEnd(node *dataNode) {
	if this.Head == nil && this.Tail == nil {
		this.Head = node
		this.Tail = node
		return
	}
	//加到队尾
	this.Tail.next = node
	node.pre = this.Tail
	node.next = nil
	this.Tail = node //节点变成最后一个节点
}

func (this *Solution) set(key int, value int) {
	// write code here
	//新增或者修改?
	node, ok := this.HashStorage[key]
	if ok {
		//修改
		node.Val = value
		this.moveNodeToTheEnd(node)
		return
	}

	//插入的情况;
	if len(this.HashStorage) >= this.Cap {
		//弹出首个元素
		tmpV := this.Head.Key
		this.deleteFromList(this.Head)
		delete(this.HashStorage, tmpV)
	}
	//加入一个元素
	node = &dataNode{
		Key: key,
		Val: value,
	}
	this.HashStorage[key] = node
	this.addNodeToEnd(node)
	return

}

全部评论

相关推荐

05-08 17:12
郑州大学 Java
点赞 评论 收藏
分享
个人背景:学院二本计科专业 大二开始实习个人经历:安克创新 、理想汽车、字节跳动碎碎念:我做事只有三分钟热度。看到进了大厂的同学,我会羡慕,也会跟着努力上进;但遇到好看的小说,我又会放下手头的事沉迷其中,之前的坚持也就中断了。我有些自卑,总觉得自己学历和外貌都不够好。之前偶然在网上受到关注,我就喜欢上了上网,因为这里有很多人认可我。但我也很在意别人的评价,偶尔看到嘲讽的言论,会触发我的自卑情绪,让我感到愤怒。有时候我会强硬地回怼,有时候又会懦弱地选择无视。我也有虚荣心。不管是拿到安克、理想还是字节的机会,我在分享的时候都会带着这份心思。我会特意强调自己学历不好,是为了衬托出过程的艰难,以此显得自己更厉害。我知道,人往往会炫耀自己缺少的东西,来掩盖内心的空洞。我总想着走捷径,不太喜欢踏踏实实地做事。找实习的时候,我花了更多时间在研究面试技巧上,而不是提升专业能力。我会反复听面试录音分析技巧,看面试教程学习怎么和不同的面试官沟通,还会每天自言自语练习语言表达,同学都觉得我有点奇怪。我的实习生涯里,侥幸和运气占了很大一部分。我总在想,如果有一天我失去了这份幸运,这些特质可能会让我一蹶不振。ps: 很多人会问我学习路线和经验 但是就像我上面说的 我的实习过程靠的很多是关键节点的运气 技术上面我可能不如很多人  所以请大家理性求助和理性参考我的回答 附上我的投递记录
我的offer在哪里...:从去年看到现在,飞升哥就是榜样
我的求职进度条
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务