- Translate each rule into one explicit state update.
- Maintain the invariant after every processed item.
- Return the accumulated state once all relevant input has been handled.
Code notes
- 112 lines of Python from the credited upstream file all-oone-data-structure.py.
- The implementation visibly relies on sequence storage, ordered lookup.
- No explicit loop blocks detected.
Complexity
Count the number and nesting of passes over the input, then include the maintained containers in the memory estimate.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 4class Node(object):5 """6 double linked list node7 """8 def __init__(self, value, keys):9 self.value = value10 self.keys = keys11 self.prev = None12 self.next = None13 14 15class LinkedList(object):16 def __init__(self):17 self.head, self.tail = Node(0, set()), Node(0, set())18 self.head.next, self.tail.prev = self.tail, self.head19 20 def insert(self, pos, node):21 node.prev, node.next = pos.prev, pos22 pos.prev.next, pos.prev = node, node23 return node24 25 def erase(self, node):26 node.prev.next, node.next.prev = node.next, node.prev27 del node28 29 def empty(self):30 return self.head.next is self.tail31 32 def begin(self):33 return self.head.next34 35 def end(self):36 return self.tail37 38 def front(self):39 return self.head.next40 41 def back(self):42 return self.tail.prev43 44 45class AllOne(object):46 47 def __init__(self):48 """49 Initialize your data structure here.50 """51 self.bucket_of_key = {}52 self.buckets = LinkedList()53 54 def inc(self, key):55 """56 Inserts a new key <Key> with value 1. Or increments an existing key by 1.57 :type key: str58 :rtype: void59 """60 if key not in self.bucket_of_key:61 self.bucket_of_key[key] = self.buckets.insert(self.buckets.begin(), Node(0, set([key])))62 63 bucket, next_bucket = self.bucket_of_key[key], self.bucket_of_key[key].next64 if next_bucket is self.buckets.end() or next_bucket.value > bucket.value+1:65 next_bucket = self.buckets.insert(next_bucket, Node(bucket.value+1, set()))66 next_bucket.keys.add(key)67 self.bucket_of_key[key] = next_bucket68 69 bucket.keys.remove(key)70 if not bucket.keys:71 self.buckets.erase(bucket)72 73 def dec(self, key):74 """75 Decrements an existing key by 1. If Key's value is 1, remove it from the data structure.76 :type key: str77 :rtype: void78 """79 if key not in self.bucket_of_key:80 return81 82 bucket, prev_bucket = self.bucket_of_key[key], self.bucket_of_key[key].prev83 self.bucket_of_key.pop(key, None)84 if bucket.value > 1:85 if bucket is self.buckets.begin() or prev_bucket.value < bucket.value-1:86 prev_bucket = self.buckets.insert(bucket, Node(bucket.value-1, set()))87 prev_bucket.keys.add(key)88 self.bucket_of_key[key] = prev_bucket89 90 bucket.keys.remove(key)91 if not bucket.keys:92 self.buckets.erase(bucket)93 94 def getMaxKey(self):95 """96 Returns one of the keys with maximal value.97 :rtype: str98 """99 if self.buckets.empty():100 return ""101 return iter(self.buckets.back().keys).next()102 103 def getMinKey(self):104 """105 Returns one of the keys with Minimal value.106 :rtype: str107 """108 if self.buckets.empty():109 return ""110 return iter(self.buckets.front().keys).next()111 112