add new solutions
This commit is contained in:
parent
9c2c959a9b
commit
9a10695e8c
29 changed files with 1074 additions and 2 deletions
112
solutions/1/q146/solution.go
Normal file
112
solutions/1/q146/solution.go
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
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);
|
||||
*/
|
||||
Loading…
Add table
Add a link
Reference in a new issue