Skip to content

Commit f04a465

Browse files
committedMar 16, 2022
feat: add solutions to lc problem: No.0432
No.0432.All O`one Data Structure
1 parent 37ed60f commit f04a465

File tree

5 files changed

+530
-5
lines changed

5 files changed

+530
-5
lines changed
 

‎solution/0300-0399/0327.Count of Range Sum/README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@
5050

5151
这两个操作的时间复杂度均为 `O(log n)`
5252

53-
本题中,对于每个下标 j,以 j 为右端点的下标对的数量,就等于 `preSum[1..j]` 中的所有整数,出现在区间 `[preSum[j] - upper, preSum[j] - lower]` 的次数。我们可以用树状数组,从左到右扫描前缀和数组,每遇到一个前缀和 s,就在树状数组中查询区间 `[preSum[j] - upper, preSum[j] - lower]` 内的整数的数量,随后将 s 更新至树状数组。
53+
本题中,对于每个下标 j,以 j 为右端点的下标对的数量,就等于 `preSum[1..j]` 中的所有整数,出现在区间 `[preSum[j] - upper, preSum[j] - lower]` 的次数。
54+
55+
> `lower <= preSum[j] - preSum[i - 1] <= upper`,变形得 `preSum[j] - upper <= preSum[i - 1] <= preSum[j] - lower`
56+
57+
我们可以用树状数组,从左到右扫描前缀和数组,每遇到一个前缀和 s,就在树状数组中查询区间 `[preSum[j] - upper, preSum[j] - lower]` 内的整数的数量,随后将 s 更新至树状数组。
5458

5559
<!-- tabs:start -->
5660

‎solution/0400-0499/0432.All O`one Data Structure/README.md

+175-2
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,188 @@ allOne.getMinKey(); // 返回 "leet"
6262
<!-- 这里可写当前语言的特殊实现逻辑 -->
6363

6464
```python
65-
65+
class Node:
66+
def __init__(self, key='', cnt=0):
67+
self.prev = None
68+
self.next = None
69+
self.cnt = cnt
70+
self.keys = {key}
71+
72+
def insert(self, node):
73+
node.prev = self
74+
node.next = self.next
75+
node.prev.next = node
76+
node.next.prev = node
77+
return node
78+
79+
def remove(self):
80+
self.prev.next = self.next
81+
self.next.prev = self.prev
82+
83+
84+
class AllOne:
85+
86+
def __init__(self):
87+
self.root = Node()
88+
self.root.next = self.root
89+
self.root.prev = self.root
90+
self.nodes = {}
91+
92+
def inc(self, key: str) -> None:
93+
root, nodes = self.root, self.nodes
94+
if key not in nodes:
95+
if root.next == root or root.next.cnt > 1:
96+
nodes[key] = root.insert(Node(key, 1))
97+
else:
98+
root.next.keys.add(key)
99+
nodes[key] = root.next
100+
else:
101+
curr = nodes[key]
102+
next = curr.next
103+
if next == root or next.cnt > curr.cnt + 1:
104+
nodes[key] = curr.insert(Node(key, curr.cnt + 1))
105+
else:
106+
next.keys.add(key)
107+
nodes[key] = next
108+
curr.keys.discard(key)
109+
if not curr.keys:
110+
curr.remove()
111+
112+
def dec(self, key: str) -> None:
113+
root, nodes = self.root, self.nodes
114+
curr = nodes[key]
115+
if curr.cnt == 1:
116+
nodes.pop(key)
117+
else:
118+
prev = curr.prev
119+
if prev == root or prev.cnt < curr.cnt - 1:
120+
nodes[key] = prev.insert(Node(key, curr.cnt - 1))
121+
else:
122+
prev.keys.add(key)
123+
nodes[key] = prev
124+
curr.keys.discard(key)
125+
if not curr.keys:
126+
curr.remove()
127+
128+
def getMaxKey(self) -> str:
129+
return next(iter(self.root.prev.keys))
130+
131+
def getMinKey(self) -> str:
132+
return next(iter(self.root.next.keys))
133+
134+
135+
# Your AllOne object will be instantiated and called as such:
136+
# obj = AllOne()
137+
# obj.inc(key)
138+
# obj.dec(key)
139+
# param_3 = obj.getMaxKey()
140+
# param_4 = obj.getMinKey()
66141
```
67142

68143
### **Java**
69144

70145
<!-- 这里可写当前语言的特殊实现逻辑 -->
71146

72147
```java
73-
148+
class AllOne {
149+
Node root = new Node();
150+
Map<String, Node> nodes = new HashMap<>();
151+
152+
public AllOne() {
153+
root.next = root;
154+
root.prev = root;
155+
}
156+
157+
public void inc(String key) {
158+
if (!nodes.containsKey(key)) {
159+
if (root.next == root || root.next.cnt > 1) {
160+
nodes.put(key, root.insert(new Node(key, 1)));
161+
} else {
162+
root.next.keys.add(key);
163+
nodes.put(key, root.next);
164+
}
165+
} else {
166+
Node curr = nodes.get(key);
167+
Node next = curr.next;
168+
if (next == root || next.cnt > curr.cnt + 1) {
169+
nodes.put(key, curr.insert(new Node(key, curr.cnt + 1)));
170+
} else {
171+
next.keys.add(key);
172+
nodes.put(key, next);
173+
}
174+
curr.keys.remove(key);
175+
if (curr.keys.isEmpty()) {
176+
curr.remove();
177+
}
178+
}
179+
}
180+
181+
public void dec(String key) {
182+
Node curr = nodes.get(key);
183+
if (curr.cnt == 1) {
184+
nodes.remove(key);
185+
} else {
186+
Node prev = curr.prev;
187+
if (prev == root || prev.cnt < curr.cnt - 1) {
188+
nodes.put(key, prev.insert(new Node(key, curr.cnt - 1)));
189+
} else {
190+
prev.keys.add(key);
191+
nodes.put(key, prev);
192+
}
193+
}
194+
195+
curr.keys.remove(key);
196+
if (curr.keys.isEmpty()) {
197+
curr.remove();
198+
}
199+
}
200+
201+
public String getMaxKey() {
202+
return root.prev.keys.iterator().next();
203+
}
204+
205+
public String getMinKey() {
206+
return root.next.keys.iterator().next();
207+
}
208+
}
209+
210+
class Node {
211+
Node prev;
212+
Node next;
213+
int cnt;
214+
Set<String> keys = new HashSet<>();
215+
216+
public Node() {
217+
this("", 0);
218+
}
219+
220+
public Node(String key, int cnt) {
221+
this.cnt = cnt;
222+
keys.add(key);
223+
}
224+
225+
public Node insert(Node node) {
226+
node.prev = this;
227+
node.next = this.next;
228+
node.prev.next = node;
229+
node.next.prev = node;
230+
return node;
231+
}
232+
233+
public void remove() {
234+
this.prev.next = this.next;
235+
this.next.prev = this.prev;
236+
}
237+
}
238+
239+
/**
240+
* Your AllOne object will be instantiated and called as such:
241+
* AllOne obj = new AllOne();
242+
* obj.inc(key);
243+
* obj.dec(key);
244+
* String param_3 = obj.getMaxKey();
245+
* String param_4 = obj.getMinKey();
246+
*/
74247
```
75248

76249
### **...**

‎solution/0400-0499/0432.All O`one Data Structure/README_EN.md

+175-2
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,186 @@ allOne.getMinKey(); // return &quot;leet&quot;
5454
### **Python3**
5555

5656
```python
57-
57+
class Node:
58+
def __init__(self, key='', cnt=0):
59+
self.prev = None
60+
self.next = None
61+
self.cnt = cnt
62+
self.keys = {key}
63+
64+
def insert(self, node):
65+
node.prev = self
66+
node.next = self.next
67+
node.prev.next = node
68+
node.next.prev = node
69+
return node
70+
71+
def remove(self):
72+
self.prev.next = self.next
73+
self.next.prev = self.prev
74+
75+
76+
class AllOne:
77+
78+
def __init__(self):
79+
self.root = Node()
80+
self.root.next = self.root
81+
self.root.prev = self.root
82+
self.nodes = {}
83+
84+
def inc(self, key: str) -> None:
85+
root, nodes = self.root, self.nodes
86+
if key not in nodes:
87+
if root.next == root or root.next.cnt > 1:
88+
nodes[key] = root.insert(Node(key, 1))
89+
else:
90+
root.next.keys.add(key)
91+
nodes[key] = root.next
92+
else:
93+
curr = nodes[key]
94+
next = curr.next
95+
if next == root or next.cnt > curr.cnt + 1:
96+
nodes[key] = curr.insert(Node(key, curr.cnt + 1))
97+
else:
98+
next.keys.add(key)
99+
nodes[key] = next
100+
curr.keys.discard(key)
101+
if not curr.keys:
102+
curr.remove()
103+
104+
def dec(self, key: str) -> None:
105+
root, nodes = self.root, self.nodes
106+
curr = nodes[key]
107+
if curr.cnt == 1:
108+
nodes.pop(key)
109+
else:
110+
prev = curr.prev
111+
if prev == root or prev.cnt < curr.cnt - 1:
112+
nodes[key] = prev.insert(Node(key, curr.cnt - 1))
113+
else:
114+
prev.keys.add(key)
115+
nodes[key] = prev
116+
curr.keys.discard(key)
117+
if not curr.keys:
118+
curr.remove()
119+
120+
def getMaxKey(self) -> str:
121+
return next(iter(self.root.prev.keys))
122+
123+
def getMinKey(self) -> str:
124+
return next(iter(self.root.next.keys))
125+
126+
127+
# Your AllOne object will be instantiated and called as such:
128+
# obj = AllOne()
129+
# obj.inc(key)
130+
# obj.dec(key)
131+
# param_3 = obj.getMaxKey()
132+
# param_4 = obj.getMinKey()
58133
```
59134

60135
### **Java**
61136

62137
```java
63-
138+
class AllOne {
139+
Node root = new Node();
140+
Map<String, Node> nodes = new HashMap<>();
141+
142+
public AllOne() {
143+
root.next = root;
144+
root.prev = root;
145+
}
146+
147+
public void inc(String key) {
148+
if (!nodes.containsKey(key)) {
149+
if (root.next == root || root.next.cnt > 1) {
150+
nodes.put(key, root.insert(new Node(key, 1)));
151+
} else {
152+
root.next.keys.add(key);
153+
nodes.put(key, root.next);
154+
}
155+
} else {
156+
Node curr = nodes.get(key);
157+
Node next = curr.next;
158+
if (next == root || next.cnt > curr.cnt + 1) {
159+
nodes.put(key, curr.insert(new Node(key, curr.cnt + 1)));
160+
} else {
161+
next.keys.add(key);
162+
nodes.put(key, next);
163+
}
164+
curr.keys.remove(key);
165+
if (curr.keys.isEmpty()) {
166+
curr.remove();
167+
}
168+
}
169+
}
170+
171+
public void dec(String key) {
172+
Node curr = nodes.get(key);
173+
if (curr.cnt == 1) {
174+
nodes.remove(key);
175+
} else {
176+
Node prev = curr.prev;
177+
if (prev == root || prev.cnt < curr.cnt - 1) {
178+
nodes.put(key, prev.insert(new Node(key, curr.cnt - 1)));
179+
} else {
180+
prev.keys.add(key);
181+
nodes.put(key, prev);
182+
}
183+
}
184+
185+
curr.keys.remove(key);
186+
if (curr.keys.isEmpty()) {
187+
curr.remove();
188+
}
189+
}
190+
191+
public String getMaxKey() {
192+
return root.prev.keys.iterator().next();
193+
}
194+
195+
public String getMinKey() {
196+
return root.next.keys.iterator().next();
197+
}
198+
}
199+
200+
class Node {
201+
Node prev;
202+
Node next;
203+
int cnt;
204+
Set<String> keys = new HashSet<>();
205+
206+
public Node() {
207+
this("", 0);
208+
}
209+
210+
public Node(String key, int cnt) {
211+
this.cnt = cnt;
212+
keys.add(key);
213+
}
214+
215+
public Node insert(Node node) {
216+
node.prev = this;
217+
node.next = this.next;
218+
node.prev.next = node;
219+
node.next.prev = node;
220+
return node;
221+
}
222+
223+
public void remove() {
224+
this.prev.next = this.next;
225+
this.next.prev = this.prev;
226+
}
227+
}
228+
229+
/**
230+
* Your AllOne object will be instantiated and called as such:
231+
* AllOne obj = new AllOne();
232+
* obj.inc(key);
233+
* obj.dec(key);
234+
* String param_3 = obj.getMaxKey();
235+
* String param_4 = obj.getMinKey();
236+
*/
64237
```
65238

66239
### **...**

0 commit comments

Comments
 (0)