Main idea is to maintain a list of Bucket's, each Bucket contains all keys with the same count.

head and tail can ensure both getMaxKey() and getMaxKey() be done in O(1).

keyCountMap maintains the count of keys, countBucketMap provides O(1) access to a specific Bucket with given count. Deleting and adding a Bucket in the Bucket list cost O(1), so both inc() and dec() take strict O(1) time.

it will be fine with the INT_MIN and INT_MAX because the head and tail are only used as dummy nodes.

The main idea is to maintain an ordered two-dimensional doubly-linked list (let's call it matrix for convenience), of which each row is corresponding to a value and all of the keys in the same row have the same value.

Suppose we get the following key-value pairs after some increment operations. ("A": 4 means "A" is increased four times so its value is 4, and so on.)

If we can guarantee the rows are in descending order in terms of value, then GetMaxKey()/GetMinKey() will be easy to implement in O(1) time complexity. Because the first key in the first row will always has the maximal value, and the first key in the last row will always has the minimal value.

Once a key is increased, we move the key from current row to last row if last_row.val = current_row.val + 1. Otherwise, we insert a new row before current row with vallue current_row.val + 1, and move the key to to the new row. The logic of decrement operation is similar. Obviously, by doing this, the rows will keep its descending order.

Now the key problem is how to maintain the matrix in O(1) runtime when increase/decrease a key by 1.

The answer is hash map. By using a hash map to track the position of a key in the matrix, we can access a key in the matrix in O(1). And since we use linked list to store the matrix, thus insert/move operations will all be O(1).

The psudocode of Inc() is as follows(Dec() is similar).

if the key isn't in the matrix:
if the matrix is empty or the value of the last row isn't 1:
insert a newrowwithvalue1to the endof the matrix, and put the keyin the newrow;
else:
put the key in the last row of the matrix;
else:
if the key is at the first row or last_row.value != current_row.value + 1:
insert a newrowbeforecurrentrow, withvalue current_row.value + 1, andmove the keyto the newrow;
else:
move the key from current row to last row;