|
| 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