package q146 type lruNode struct { key, val int prev, next *lruNode } type LRUCache struct { cap int index map[int]*lruNode head, tail *lruNode nodes []lruNode p int } func Constructor(capacity int) LRUCache { return LRUCache{ cap: capacity, index: make(map[int]*lruNode, capacity), nodes: make([]lruNode, capacity), } } func (c *LRUCache) alloc() *lruNode { if c.p < len(c.nodes) { c.p++ return &c.nodes[c.p-1] } return nil } func (c *LRUCache) touch(node *lruNode) { if node.prev == nil { return } if c.tail == node { c.tail = node.prev } else { node.next.prev = node.prev } node.prev.next = node.next node.prev = nil node.next = c.head c.head.prev = node c.head = node } func (c *LRUCache) evict() *lruNode { if len(c.index) < c.cap { return nil } node := c.tail delete(c.index, node.key) if node.prev == nil { c.head, c.tail = nil, nil } else { c.tail = node.prev c.tail.next = nil } return node } func (c *LRUCache) Get(key int) int { node := c.index[key] if node == nil { return -1 } c.touch(node) return node.val } func (c *LRUCache) Put(key int, value int) { if c.cap == 0 { return } node := c.index[key] if node != nil { node.val = value c.touch(node) return } node = c.alloc() if node == nil { node = c.evict() *node = lruNode{} // clear } node.key, node.val = key, value c.index[key] = node node.next = c.head if c.head != nil { c.head.prev = node } c.head = node if c.tail == nil { c.tail = node } } /** * Your LRUCache object will be instantiated and called as such: * obj := Constructor(capacity); * param_1 := obj.Get(key); * obj.Put(key,value); */