forked from xhofe/daily-problem-of-leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path16-all-oone-data-structure.go
111 lines (104 loc) · 2.39 KB
/
16-all-oone-data-structure.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
// https://leetcode-cn.com/problems/all-oone-data-structure/
type Node struct {
prev *Node
next *Node
count int
str string
}
type AllOne struct {
head *Node
tail *Node
m map[string]*Node
}
func Constructor() AllOne {
return AllOne{m: make(map[string]*Node)}
}
func (this *AllOne) Inc(key string) {
node, ok := this.m[key]
if ok {
// 如果存在,加1并向后移动node
node.count++
if node.next != nil && node.count > node.next.count {
next := node.next
// 这里的复杂度并不是O(1) 正确的做法应该是将相同count的string用一个set存到一个节点中,就不用查找了
for next.next != nil && next.next.count == next.count {
next = next.next
}
node.str, next.str = next.str, node.str
node.count, next.count = next.count, node.count
this.m[node.str] = node
this.m[next.str] = next
}
} else {
// 不存在 创建 并放到头部
node = &Node{count: 1, str: key}
this.m[key] = node
if this.head == nil {
this.head = node
this.tail = node
} else {
head := this.head
this.head = node
node.next = head
head.prev = node
}
}
}
// 1 - 2 - 3
func (this *AllOne) Dec(key string) {
node, _ := this.m[key]
node.count--
if node.count == 0 {
// 移除
delete(this.m, key)
prev, next := node.prev, node.next
if this.head == this.tail {
this.head = nil
this.tail = nil
} else {
if prev != nil {
prev.next = next
} else {
this.head = next
}
if next != nil {
next.prev = prev
} else {
this.tail = prev
}
}
} else {
// 移动
if node.prev != nil && node.prev.count > node.count {
prev := node.prev
// 同上 复杂度非O(1)
for prev.prev != nil && prev.prev.count == prev.count {
prev = prev.prev
}
prev.str, node.str = node.str, prev.str
prev.count, node.count = node.count, prev.count
this.m[node.str] = node
this.m[prev.str] = prev
}
}
}
func (this *AllOne) GetMaxKey() string {
if this.tail == nil {
return ""
}
return this.tail.str
}
func (this *AllOne) GetMinKey() string {
if this.head == nil {
return ""
}
return this.head.str
}
/**
* Your AllOne object will be instantiated and called as such:
* obj := Constructor();
* obj.Inc(key);
* obj.Dec(key);
* param_3 := obj.GetMaxKey();
* param_4 := obj.GetMinKey();
*/