例题
146. LRU 缓存机制
package main func main() { /** * Your LRUCache object will be instantiated and called as such: * obj := Constructor(capacity); * param_1 := obj.Get(key); * obj.Put(key,value); */ obj := Constructor(2) obj.Put(1,1) obj.Put(2,2) println(obj.Get(1)) obj.Put(3,3) println(obj.Get(2)) obj.Put(4,4) println(obj.Get(1)) println(obj.Get(3)) println(obj.Get(4)) } //["LRUCache","put","put","get","put","get","put","get","get","get"] //[[2],[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]] type LRUCache struct { size int capacity int mymap map[int]*Node head,tail *Node } type Node struct{ key int val int pre , next *Node } func Constructor(capacity int) LRUCache { lru := LRUCache{ size: 0, capacity: capacity, mymap: make(map[int]*Node), head: &Node{ 0, 0, nil, nil, }, tail: &Node{ 0, 0, nil, nil, }, } lru.head.next = lru.tail lru.tail.pre = lru.head return lru } func (this *LRUCache) RemoveNode(node *Node) { node.pre.next = node.next node.next.pre = node.pre } func (this *LRUCache)AddHead(node *Node) { this.head.next.pre = node node.next = this.head.next this.head.next = node node.pre = this.head } func (this *LRUCache)RmoveTail() *Node{ res := this.tail.pre this.tail.pre.pre.next = this.tail this.tail.pre = this.tail.pre.pre return res } func (this *LRUCache) Get(key int) int { val ,e := this.mymap[key] if !e{ return -1 } this.RemoveNode(val) this.AddHead(val) return val.val } func (this *LRUCache) Put(key int, value int) { val , e := this.mymap[key] // 不存在 if !e{ tep := &Node{ key: key, val: value, pre: nil, next: nil, } this.AddHead(tep) this.mymap[key] = tep this.size++ if this.size > this.capacity { this.size -- ddkey := this.RmoveTail() delete(this.mymap,ddkey.key) } }else{ val.val = value this.RemoveNode(val) this.AddHead(val) } }
思想:哈希+双向链表
341. 扁平化嵌套列表迭代器
/** * // This is the interface that allows for creating nested lists. * // You should not implement it, or speculate about its implementation * type NestedInteger struct { * } * * // Return true if this NestedInteger holds a single integer, rather than a nested list. * func (this NestedInteger) IsInteger() bool {} * * // Return the single integer that this NestedInteger holds, if it holds a single integer * // The result is undefined if this NestedInteger holds a nested list * // So before calling this method, you should have a check * func (this NestedInteger) GetInteger() int {} * * // Set this NestedInteger to hold a single integer. * func (n *NestedInteger) SetInteger(value int) {} * * // Set this NestedInteger to hold a nested list and adds a nested integer to it. * func (this *NestedInteger) Add(elem NestedInteger) {} * * // Return the nested list that this NestedInteger holds, if it holds a nested list * // The list length is zero if this NestedInteger holds a single integer * // You can access NestedInteger's List element directly if you want to modify it * func (this NestedInteger) GetList() []*NestedInteger {} */ type NestedIterator struct { nums []int index int max int } func Constructor(nestedList []*NestedInteger) *NestedIterator { res := NestedIterator{ make([]int,0), 0, 0, } clen := len(nestedList) for i:=0;i<clen;i++{ if nestedList[i].IsInteger(){ res.nums = append(res.nums,nestedList[i].GetInteger()) }else{ res.addToSlice(nestedList[i]) } } res.max = len(res.nums) return &res } func (this *NestedIterator)addToSlice(n *NestedInteger){ if n.IsInteger(){ this.nums = append(this.nums,n.GetInteger()) return }else{ tep := n.GetList() clen := len(tep) for i:=0;i<clen;i++{ this.addToSlice(tep[i]) } } } func (this *NestedIterator) Next() int { t := this.index this.index++ return this.nums[t] } func (this *NestedIterator) HasNext() bool { if this.index < this.max{ return true }else { return false } }
380. O(1) 时间插⼊、删除和获取随机元素
type RandomizedSet struct { mymap map[int]int nums []int len int } func Constructor() RandomizedSet { res := RandomizedSet{ make(map[int]int), make([]int,0), 0, } return res } func (this *RandomizedSet) Insert(val int) bool { _ ,e := this.mymap[val] if e{ return false } this.mymap[val] = this.len this.len ++ this.nums = append(this.nums,val) return true } func (this *RandomizedSet) Remove(val int) bool { index ,e := this.mymap[val] if !e{ return false } lenKey := this.nums[this.len-1] this.mymap[lenKey] = index this.nums[index] = lenKey this.nums = this.nums[:this.len-1] this.len -- delete(this.mymap,val) return true } func (this *RandomizedSet) GetRandom() int { return this.nums[rand.Intn(this.len)] }
思想:哈希+slice,在进行移除slice的时候,可以考虑先进行置换在进行移除,这样就不会影响哈希对应的下标,一般是将移除的index和末尾进行交换之后在进行移除。
460. LFU 缓存
895. 最⼤频率栈
type FreqStack struct { keyTime map[int]int timeSlice map[int][]int MAX int } func Constructor() FreqStack { res := FreqStack{ make(map[int]int), make(map[int][]int), 0, } return res } func (this *FreqStack) Push(val int) { // 存在 if time, e := this.keyTime[val]; !e { this.keyTime[val] = 1 if slice , e2 := this.timeSlice[1];!e2{ cslice := []int{val} this.timeSlice[1] = cslice }else{ slice = append(slice , val) this.timeSlice[1] = slice } if this.MAX < 1{ this.MAX = 1 } } else {// 不存在 this.keyTime[val] = time + 1 time ++ if slice , e2 := this.timeSlice[time];!e2{ cslice := []int{val} this.timeSlice[time] = cslice }else{ slice = append(slice , val) this.timeSlice[time] = slice } if this.MAX < time{ this.MAX = time } } } func (this *FreqStack) Pop() int { for this.MAX !=0 { if len(this.timeSlice[this.MAX]) > 0{ tepSlice := this.timeSlice[this.MAX] res := tepSlice[len(tepSlice) -1 ] this.timeSlice[this.MAX] = tepSlice[:len(tepSlice)-1] ctime := this.keyTime[res] ctime -- if ctime <= 0{ delete(this.keyTime,res) }else{ this.keyTime[res] =ctime } return res }else{ this.MAX -- } } return -1 } /** * Your FreqStack object will be instantiated and called as such: * obj := Constructor(); * obj.Push(val); * param_2 := obj.Pop(); */