-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlru-cache.go
108 lines (93 loc) · 2.27 KB
/
lru-cache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package main
import "fmt"
// source: https://leetcode.com/problems/lru-cache/
type LRUCacheNode struct {
key, value int
prev, next *LRUCacheNode
}
type LRUCache struct {
cap int
values map[int]*LRUCacheNode
head, tail *LRUCacheNode
}
func Constructor(capacity int) LRUCache {
cache := LRUCache{
cap: capacity,
values: make(map[int]*LRUCacheNode, capacity),
head: new(LRUCacheNode),
tail: new(LRUCacheNode),
}
cache.head.next = cache.tail
cache.tail.prev = cache.head
return cache
}
func (c *LRUCache) Get(key int) int {
if node, ok := c.values[key]; ok {
c.bumpNode(node)
return node.value
}
return -1
}
func (c *LRUCache) Put(key int, value int) {
if node, ok := c.values[key]; ok {
node.value = value
c.bumpNode(node)
return
}
node := &LRUCacheNode{
key: key,
value: value,
}
c.values[key] = node
c.bumpNode(node)
if len(c.values) > c.cap {
delete(c.values, c.tail.prev.key)
c.tail.prev.prev.next = c.tail
c.tail.prev = c.tail.prev.prev
}
}
func (c *LRUCache) bumpNode(node *LRUCacheNode) {
if c.head.next == node {
return
}
if node.prev != nil {
node.prev.next = node.next
}
if node.next != nil {
node.next.prev = node.prev
}
node.prev = c.head
node.next = c.head.next
c.head.next.prev = node
c.head.next = node
}
func main() {
var c1 = Constructor(2)
c1.Put(1, 1) // cache is {1=1}
c1.Put(2, 2) // cache is {1=1, 2=2}
fmt.Println(c1.Get(1)) // return 1
c1.Put(3, 3) // LRU key was 2, evicts key 2, cache is {1=1, 3=3}
fmt.Println(c1.Get(2)) // returns -1 (not found)
c1.Put(4, 4) // LRU key was 1, evicts key 1, cache is {4=4, 3=3}
fmt.Println(c1.Get(1)) // return -1 (not found)
fmt.Println(c1.Get(3)) // return 3
fmt.Println(c1.Get(4)) // return 4
println()
//["LRUCache","put","put","put","put","get","get","get","get","put","get","get","get","get","get"]
//[[3], [1,1],[2,2],[3,3],[4,4],[4], [3], [2], [1], [5,5],[1], [2], [3], [4], [5]]
var c2 = Constructor(3)
c2.Put(1, 1)
c2.Put(2, 2)
c2.Put(3, 3)
c2.Put(4, 4)
fmt.Println(c2.Get(4))
fmt.Println(c2.Get(3))
fmt.Println(c2.Get(2))
fmt.Println(c2.Get(1))
c2.Put(5, 5)
fmt.Println(c2.Get(1))
fmt.Println(c2.Get(2))
fmt.Println(c2.Get(3))
fmt.Println(c2.Get(4))
fmt.Println(c2.Get(5))
}