forked from doocs/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSolution.go
120 lines (104 loc) · 1.76 KB
/
Solution.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
109
110
111
112
113
114
115
116
117
118
119
120
type LFUCache struct {
cache map[int]*node
freqMap map[int]*list
minFreq int
capacity int
}
func Constructor(capacity int) LFUCache {
return LFUCache{
cache: make(map[int]*node),
freqMap: make(map[int]*list),
capacity: capacity,
}
}
func (this *LFUCache) Get(key int) int {
if this.capacity == 0 {
return -1
}
n, ok := this.cache[key]
if !ok {
return -1
}
this.incrFreq(n)
return n.val
}
func (this *LFUCache) Put(key int, value int) {
if this.capacity == 0 {
return
}
n, ok := this.cache[key]
if ok {
n.val = value
this.incrFreq(n)
return
}
if len(this.cache) == this.capacity {
l := this.freqMap[this.minFreq]
delete(this.cache, l.removeBack().key)
}
n = &node{key: key, val: value, freq: 1}
this.addNode(n)
this.cache[key] = n
this.minFreq = 1
}
func (this *LFUCache) incrFreq(n *node) {
l := this.freqMap[n.freq]
l.remove(n)
if l.empty() {
delete(this.freqMap, n.freq)
if n.freq == this.minFreq {
this.minFreq++
}
}
n.freq++
this.addNode(n)
}
func (this *LFUCache) addNode(n *node) {
l, ok := this.freqMap[n.freq]
if !ok {
l = newList()
this.freqMap[n.freq] = l
}
l.pushFront(n)
}
type node struct {
key int
val int
freq int
prev *node
next *node
}
type list struct {
head *node
tail *node
}
func newList() *list {
head := new(node)
tail := new(node)
head.next = tail
tail.prev = head
return &list{
head: head,
tail: tail,
}
}
func (l *list) pushFront(n *node) {
n.prev = l.head
n.next = l.head.next
l.head.next.prev = n
l.head.next = n
}
func (l *list) remove(n *node) {
n.prev.next = n.next
n.next.prev = n.prev
n.next = nil
n.prev = nil
}
func (l *list) removeBack() *node {
n := l.tail.prev
l.remove(n)
return n
}
func (l *list) empty() bool {
return l.head.next == l.tail
}