Skip to content

Commit bacd9ee

Browse files
committed
2020-01-26 432. All O`one Data Structure
1 parent 25a5d92 commit bacd9ee

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# -*- coding: utf-8 -*-
2+
# @Author: 何睿
3+
# @Create Date: 2020-01-26 16:07:05
4+
# @Last Modified by: 何睿
5+
# @Last Modified time: 2020-01-26 16:35:40
6+
7+
8+
class Block(object):
9+
def __init__(self, val=0):
10+
self.val = val
11+
self.keys = set()
12+
self.before = None
13+
self.after = None
14+
15+
def remove(self):
16+
self.before.after = self.after
17+
self.after.before = self.before
18+
self.before, self.after = None, None
19+
20+
def insert_after(self, new_block):
21+
old_after = self.after
22+
self.after = new_block
23+
new_block.before = self
24+
new_block.after = old_after
25+
old_after.before = new_block
26+
27+
28+
class AllOne(object):
29+
def __init__(self):
30+
self.begin = Block() # sentinel
31+
self.end = Block() # sentinel
32+
self.begin.after = self.end
33+
self.end.before = self.begin
34+
self.mapping = {} # key to block
35+
36+
def inc(self, key):
37+
if not key in self.mapping: # find current block and remove key
38+
current_block = self.begin
39+
else:
40+
current_block = self.mapping[key]
41+
current_block.keys.remove(key)
42+
43+
if current_block.val + 1 != current_block.after.val: # insert new block
44+
new_block = Block(current_block.val + 1)
45+
current_block.insert_after(new_block)
46+
else:
47+
new_block = current_block.after
48+
49+
new_block.keys.add(key) # update new_block
50+
self.mapping[key] = new_block # ... and mapping of key to new_block
51+
52+
if not current_block.keys and current_block.val != 0: # delete current block if not seninel
53+
current_block.remove()
54+
55+
def dec(self, key):
56+
if not key in self.mapping:
57+
return
58+
59+
current_block = self.mapping[key]
60+
del self.mapping[key] # could use self.mapping.pop(key)
61+
current_block.keys.remove(key)
62+
63+
if current_block.val != 1:
64+
if current_block.val - 1 != current_block.before.val: # insert new block
65+
new_block = Block(current_block.val - 1)
66+
current_block.before.insert_after(new_block)
67+
else:
68+
new_block = current_block.before
69+
new_block.keys.add(key)
70+
self.mapping[key] = new_block
71+
72+
if not current_block.keys: # delete current block
73+
current_block.remove()
74+
75+
def getMaxKey(self):
76+
if self.end.before.val == 0:
77+
return ""
78+
key = self.end.before.keys.pop() # pop and add back to get arbitrary (but not random) element
79+
self.end.before.keys.add(key)
80+
return key
81+
82+
def getMinKey(self):
83+
if self.begin.after.val == 0:
84+
return ""
85+
key = self.begin.after.keys.pop()
86+
self.begin.after.keys.add(key)
87+
return key

0 commit comments

Comments
 (0)